AllPondsNoSite<-select (AllPonds, - 1 )
AllSums<-colSums (AllPondsNoSite)
AllData<-rbind (AllPondsNoSite, AllSums)
rownames (AllData)[rownames (AllData)== "1032" ] <- "sum"
#Remove doublteons
AllDataSums = AllData[,AllSums > 1 ]
ncol (AllData[,sums < 3 ])
[1] 146
#235** singletons!
#152 singltons and doubletons!
AllDataNoSing<-slice (AllDataSums, - c (1032 ))
AllDataNoSing$ sum<-rowSums (AllDataNoSing)
AllDataNoSingZero<-filter (AllDataNoSing, sum > 0 )
sumsumsPerm<-cbind (sumsums2, sitesizes$ Permanence)
colnames (sumsumsPerm)[colnames (sumsumsPerm)== "sitesizes$Permanence" ] <- "Permanence"
AllRSums<-as.data.frame (rowSums (AllPondsNoSite))
names (AllRSums)<-c ("Sum" )
sppxsites.T<-select (sppxsites, c (1 , 12 , 15 , 16 ))
names (sppxsites.T)<-c ("Site" , "ID" , "Depth" , "Canopy" )
AllSimp<-aggregate (sppxsites.T[3 : 4 ], sppxsites.T[1 : 2 ], compress)
quadvarssums<-cbind (AllSimp, AllRSums)
sumsumssite<-cbind (sumsums3, sitesizes$ Site)
colnames (sumsumssite)[colnames (sumsumssite)== "sitesizes$Site" ] <- "Site"
sumsiteraup<-subset (sumsumssite, select= c (313 ,1 : 312 ))
raup_crick=function (spXsite, plot_names_in_col1= TRUE , classic_metric= FALSE , split_ties= TRUE , reps= 9999 , set_all_species_equal= FALSE , as.distance.matrix= TRUE , report_similarity= FALSE ){
##expects a species by site matrix for spXsite, with row names for plots, or optionally plots named in column 1. By default calculates a modification of the Raup-Crick metric (standardizing the metric to range from -1 to 1 instead of 0 to 1). Specifying classic_metric=TRUE instead calculates the original Raup-Crick metric that ranges from 0 to 1. The option split_ties (defaults to TRUE) adds half of the number of null observations that are equal to the observed number of shared species to the calculation- this is highly recommended. The argument report_similarity defaults to FALSE so the function reports a dissimilarity (which is appropriate as a measure of beta diversity). Setting report_similarity=TRUE returns a measure of similarity, as Raup and Crick originally specified. If ties are split (as we recommend) the dissimilarity (default) and similarity (set report_similarity=TRUE) calculations can be flipped by multiplying by -1 (for our modification, which ranges from -1 to 1) or by subtracting the metric from 1 (for the classic metric which ranges from 0 to 1). If ties are not split (and there are ties between the observed and expected shared number of species) this conversion will not work. The argument reps specifies the number of randomizations (a minimum of 999 is recommended- default is 9999). set_all_species_equal weights all species equally in the null model instead of weighting species by frequency of occupancy.
##Note that the choice of how many plots (rows) to include has a real impact on the metric, as species and their occurrence frequencies across the set of plots is used to determine gamma and the frequency with which each species is drawn from the null model
##this section moves plot names in column 1 (if specified as being present) into the row names of the matrix and drops the column of names
if (plot_names_in_col1){
row.names (spXsite)<-spXsite[,1 ]
spXsite<-spXsite[,- 1 ]
}
## count number of sites and total species richness across all plots (gamma)
n_sites<-nrow (spXsite)
gamma<-ncol (spXsite)
##make the spXsite matrix into a pres/abs. (overwrites initial spXsite matrix):
ceiling (spXsite/ max (spXsite))->spXsite
##create an occurrence vector- used to give more weight to widely distributed species in the null model:
occur<-apply (spXsite, MARGIN= 2 , FUN= sum)
##NOT recommended- this is a non-trivial change to the metric:
##sets all species to occur with equal frequency in the null model
##e.g.- discards any occupancy frequency information
if (set_all_species_equal){
occur<-rep (1 ,gamma)
}
## determine how many unique species richness values are in the dataset
##this is used to limit the number of null communities that have to be calculated
alpha_levels<-sort (unique (apply (spXsite, MARGIN= 1 , FUN= sum)))
##make_null:
##alpha_table is used as a lookup to help identify which null distribution to use for the tests later. It contains one row for each combination of alpha richness levels.
alpha_table<-data.frame (c (NA ), c (NA ))
names (alpha_table)<-c ("smaller_alpha" , "bigger_alpha" )
col_count<-1
##null_array will hold the actual null distribution values. Each element of the array corresponds to a null distribution for each combination of alpha values. The alpha_table is used to point to the correct null distribution- the row numbers of alpha_table correspond to the [[x]] indices of the null_array. Later the function will find the row of alpha_table with the right combination of alpha values. That row number is used to identify the element of null_array that contains the correct null distribution for that combination of alpha levels.
null_array<-list ()
##looping over each combination of alpha levels:
for (a1 in 1 : length (alpha_levels)){
for (a2 in a1: length (alpha_levels)){
##build a null distribution of the number of shared species for a pair of alpha values:
null_shared_spp<-NULL
for (i in 1 : reps){
##two empty null communities of size gamma:
com1<-rep (0 ,gamma)
com2<-rep (0 ,gamma)
##add alpha1 number of species to com1, weighting by species occurrence frequencies:
com1[sample (1 : gamma, alpha_levels[a1], replace= FALSE , prob= occur)]<-1
##same for com2:
com2[sample (1 : gamma, alpha_levels[a2], replace= FALSE , prob= occur)]<-1
##how many species are shared in common?
null_shared_spp[i]<-sum ((com1+ com2)> 1 )
}
##store null distribution, record values for alpha 1 and 2 in the alpha_table to help find the correct null distribution later:
null_array[[col_count]]<-null_shared_spp
alpha_table[col_count, which (names (alpha_table)== "smaller_alpha" )]<-alpha_levels[a1]
alpha_table[col_count, which (names (alpha_table)== "bigger_alpha" )]<-alpha_levels[a2]
#increment the counter for the columns of the alpha table/ elements of the null array
col_count<-col_count+ 1
}
}
##create a new column with both alpha levels to match on:
alpha_table$ matching<-paste (alpha_table[,1 ], alpha_table[,2 ], sep= "_" )
#####################
##do the test:
##build a site by site matrix for the results, with the names of the sites in the row and col names:
results<-matrix (data= NA , nrow= n_sites, ncol= n_sites, dimnames= list (row.names (spXsite), row.names (spXsite)))
##for each pair of sites (duplicates effort now to make a full matrix instead of a half one- but this part should be minimal time as compared to the null model building)
for (i in 1 : n_sites){
for (j in 1 : n_sites){
##how many species are shared between the two sites:
n_shared_obs<-sum ((spXsite[i,]+ spXsite[j,])> 1 )
## what was the observed richness of each site?
obs_a1<-sum (spXsite[i,])
obs_a2<-sum (spXsite[j,])
##place these alphas into an object to match against alpha_table (sort so smaller alpha is first)
obs_a_pair<-sort (c (obs_a1, obs_a2))
##match against the alpha table- row index identifies which element of the null array contains the correct null distribution for the observed combination of alpha values:
null_index<-which (alpha_table$ matching== paste (obs_a_pair[1 ], obs_a_pair[2 ], sep= "_" ))
##how many null observations is the observed value tied with?
num_exact_matching_in_null<-sum (null_array[[null_index]]== n_shared_obs)
##how many null values are bigger than the observed value?
num_greater_in_null<-sum (null_array[[null_index]]> n_shared_obs)
rc<-(num_greater_in_null)/ reps
if (split_ties){
rc<-((num_greater_in_null+ (num_exact_matching_in_null)/ 2 )/ reps)
}
if (! classic_metric){
##our modification of raup crick standardizes the metric to range from -1 to 1 instead of 0 to 1
rc<-(rc- .5 )* 2
}
## at this point rc represents an index of dissimilarity- multiply by -1 to convert to a similarity as specified in the original 1979 Raup Crick paper
if (report_similarity & ! classic_metric){
rc<- rc*- 1
}
## the switch to similarity is done differently if the original 0 to 1 range of the metric is used:
if (report_similarity & classic_metric){
rc<- 1 - rc
}
##store the metric in the results matrix:
results[i,j]<-round (rc, digits= 2 )
}
}
if (as.distance.matrix){
results<-as.dist (results)
}
return (results)
}
raupy<-raup_crick (sumsiteraup, plot_names_in_col1= TRUE , classic_metric= FALSE , split_ties= TRUE , reps= 9999 , set_all_species_equal= FALSE , as.distance.matrix= TRUE , report_similarity= FALSE )
non-unique value when setting 'row.names': 㤼㸱0㤼㸲Error in `.rowNamesDF<-`(x, value = value) :
duplicate 'row.names' are not allowed
Background
Data Collection
Plots were sampled at 27 independent sites throughout a subset of the Eastern Highland Rim ecoregion (delineated in tan below). Note that some sites were also in close proximity, making them difficult to see
1031 1m^2 quadrats were sampled with differeing sample sizes per site based on the size of the site.
Data Configuration
Nearly all statistical packages require the data to be in a presence-absence form. There are several ways to do it (one of which can maintain cover values rather than changing it to binary data); I used a loop function. The result is a presence-absence matrix with Site as a column so subsamples can be organized accordingly.
Table 1. Sample of data in presence-absence format.
1.1.1
1
1
1
1
1
1
0
1.1.2
1
0
1
0
1
1
1
1.1.3
1
0
0
0
1
1
1
1.1.4
1
1
0
0
1
1
1
1.1.5
1
0
0
0
0
0
1
Diversity
Sites had widely varying observed total richness. The use of extrapolated species accumulation curves can tell us how many species are likely to be at the site based on how many were found in accumulating subsamples. However if a curve never flattens, it gives a wild estimate of richness (see Site 10).
What do the curves that made these estimates look like? Let’s take a look!
This plot is not particularly helpful other than to visualize the general span of observed and expected richnesses and sampling efforts. Examining the curves in portions of 3-4 is necessary to
These curves illustrate not only where the flattening point (expected richness) occurs, but also how quickly . Examining a curve can allow someone to estimate how many more samples would be needed to reach that point, however if doing so samples a larger area then the curve may never flatten.
Let’s see if sampling effort (# quadrats/area sampled) affected percent estimated sampling completion; if it did, that would be a big problem and I would have a lot of explaining to do to my committee.
There is no relationship between sampling effort and completion percentage (p=0.5676424). However, note that Sites 10 and 26 were flagged as outliers by the autoplot function. This inadequate sampling is likely the result of too few quadrats sampled at the wetland edge relative to the size of the wetland.
# change na. action
options (na.action = "na.fail" )
RichSites<-cbind (sitesizes, RichInts)
RichSites.t <- RichSites[ - c (1 ) ]
model1<-glm (RichnessObs~ EndDepth+ StartDepth+ DepthChange+ Latitude+ Permanence+ Area, data= RichSites.t)
resultsmodel<-dredge (model1)
importance (resultsmodel)
DepthChange EndDepth StartDepth Permanence Latitude Area
Sum of weights: 0.62 0.33 0.31 0.28 0.21 0.19
N containing models: 32 32 24 32 32 32
Depth change between spring and fall sampling appears to be the most important factor determining observed site-level richness.
# change na. action
# options(na.action = "na.fail")
#
# gme1<- glm(Sum~Depth+Canopy+Depth*Canopy+Site:ID, data= quadvarssums)
Evenness and Dominance
There appears to be a relationship between site richness and site area, but unexpectedly this relationship appears to be negative. Because the data are likely non-linear, a generalized linear model should be used to assess this relationship.
ggplot (RichInts, aes (x= Dominance, y= RichnessObs)) +
geom_point (size= 2 )+
xlab ("Species Dominance (D)" )+
ylab ("Species Richness" )+
ggtitle ("Rich sites have low dominance" )
Communities
Which sites are similar?
There may be a lot of overlap in clusters due to the nestedness of some community types. We should revisit this later using quadrats as replicates.
Are sites similar because they’re geographically closer?
heatmapColorDistance (sorensen.m.t, main = NULL ,
colorRampPalette (c ("royalblue4" , "ghostwhite" ))(299 ), margins = c (5 , 5 ))
Error in plot.new() : figure margins too large
mantel (sorensen.m.t, distance.m)
Mantel statistic based on Pearson's product-moment correlation
Call:
mantel(xdis = sorensen.m.t, ydis = distance.m)
Mantel statistic r: 0.1359
Significance: 0.037
Upper quantiles of permutations (null model):
90% 95% 97.5% 99%
0.0937 0.1228 0.1480 0.1661
Permutation: free
Number of permutations: 999
adonis (sumsumsPerm[,1 : 312 ]~ Permanence, data= sumsumsPerm, method= "bray" , binary= TRUE )
Call:
adonis(formula = sumsumsPerm[, 1:312] ~ Permanence, data = sumsumsPerm, method = "bray", binary = TRUE)
Permutation: free
Number of permutations: 999
Terms added sequentially (first to last)
Df SumsOfSqs MeanSqs F.Model R2 Pr(>F)
Permanence 1 0.5385 0.53855 1.6619 0.06233 0.057 .
Residuals 25 8.1014 0.32405 0.93767
Total 26 8.6399 1.00000
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Ordinations
# cluster<-hclust(sorensen02, method="average")
# grp<-cutree(cluster,20)
plot (sorensen.nmds02)
species scores not available
quadrat.rda<-rda (AllPonds[- 1 ])
biplot (quadrat.rda,
display= c ("sites" , "species" ),
type= c ("text" , "points" ))
ordihull (quadrat.rda, group= AllPonds$ Site)
Implications
Plant communities aren’t real. We can all go home now.
beep (sound = 3 , expr = NULL )
LS0tDQp0aXRsZTogIkRldGVybWluaXN0aWMgcHJvY2Vzc2VzIGRyaXZlIHdldGxhbmQgcGxhbnQgY29tbXVuaXR5IGNvbXBvc2l0aW9uIGFuZCBkaXZlcnNpdHkiDQphdXRob3I6ICJDLiBNLiBDaWFmcmUiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgaGlnaGxpZ2h0OiB6ZW5idXJuDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHJvd3MucHJpbnQ6IDEwDQogICAgdGhlbWU6IGpvdXJuYWwNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KIyAgIHsudGFic2V0IC50YWJzZXQtZmFkZX0NCmBgYHtyIHNldHVwLCBOT1RJQ0UgVVNFIG9mIFBBQ01BTiwgaW5jbHVkZT1GQUxTRX0NCiNpbnN0YWxsIHBhY21hbiBmaXJzdCB0byBhdXRvbWF0aWNhbGx5IGluc3RhbGwgYW5kIGxvYWQgYW55IG5lZWRlZCBwYWNrYWdlcw0KcGFjbWFuOjpwX2xvYWQoZ2dwbG90MiwgZHBseXIsIHRpZHlyLCByZXNoYXBlLCBpTkVYVCwga25pdHIsIGthYmxlRXh0cmEsIGdnZm9ydGlmeSwgZ2dwdWJyLCB2ZWdhbiwgZ2Vvc3BoZXJlLCBtY2x1c3QsIHJnZGFsLCBsZWFmbGV0LCBnZ21hcCwgY29sb3JkaXN0YW5jZSwgTXVNSW4sIGxtZTQsIGJlZXByKQ0KDQojTm90IHN1cmUgd2h5IEkga2VlcCB0aGlzIGluDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQoNCiNMb2FkIGRhdGENCnNwcHhzaXRlczwtcmVhZC5jc3YoImRhdGEvVkVHREFUQURPTkVDT1JSLmNzdiIsIGhlYWRlcj1UUlVFKQ0Kc2l0ZW5hbWVzPC1yZWFkLmNzdigiZGF0YS9TaXRlTmFtZXMuY3N2IiwgaGVhZGVyPVRSVUUpDQpzaXRlc2l6ZXM8LXJlYWQuY3N2KCJkYXRhL1NpdGVYc2l6ZTIuY3N2IiwgaGVhZGVyPVRSVUUpDQpxdWFkZGF0YXM8LXJlYWQuY3N2KCJkYXRhL3F1YWRtZXRyaWNzLmNzdiIsIGhlYWRlcj1UUlVFKQ0KcXVhZGRlcGNhbjwtcmVhZC5jc3YoImRhdGEvcXVhZGRlcGNhbi5jc3YiLCBoZWFkZXI9VFJVRSkNCmNvbG5hbWVzKHF1YWRkYXRhcylbY29sbmFtZXMocXVhZGRhdGFzKT09IkRlcHRoLi5tLiJdIDwtICJEZXB0aCINCmNvbG5hbWVzKHF1YWRkYXRhcylbY29sbmFtZXMocXVhZGRhdGFzKT09IlguLkNhbm9weSJdIDwtICJDYW5vcHkiDQpjb2xuYW1lcyhxdWFkZGF0YXMpW2NvbG5hbWVzKHF1YWRkYXRhcyk9PSJQb25kIl0gPC0gIlNpdGUiDQpzaXRlX3BvaW50cyA8LSBzZWxlY3Qoc2l0ZXNpemVzLCBjKCJTaXRlIiwgIkxhdGl0dWRlIiwgIkxvbmdpdHVkZSIpKQ0KI05vdGU6IHRoZXJlIGlzIG5vIFNpdGUgMTU7IGl0IHdhcyBkaXRjaGVkIGhhbGZ3YXkgdGhyb3VnaCBzYW1wbGluZyBiZWNhdXNlIGl0IHdhcyBub3QgaW5kZXBlbmRlbnQgZnJvbSBTaXRlIDE0Lg0KDQpgYGANCg0KDQpgYGB7ciBTdGF0aWMgbWFwIHByZXAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIEVIUmEgPC0gcmVhZE9HUigiTWFwcHlCaXRzL2Eua21sIikNCiMgRUhSYiA8LSByZWFkT0dSKCJNYXBweUJpdHMvYi5rbWwiKQ0KIyBFSFJjIDwtIHJlYWRPR1IoIk1hcHB5Qml0cy9jLmttbCIpDQojIEVIUmQgPC0gcmVhZE9HUigiTWFwcHlCaXRzL2Qua21sIikNCiMgRUhSZSA8LSByZWFkT0dSKCJNYXBweUJpdHMvZS5rbWwiKQ0KIyBFSFJmIDwtIHJlYWRPR1IoIk1hcHB5Qml0cy9mLmttbCIpDQojIEVIUmcgPC0gcmVhZE9HUigiTWFwcHlCaXRzL2cua21sIikNCiMgRUhSaCA8LSByZWFkT0dSKCJNYXBweUJpdHMvaC5rbWwiKQ0KIyBFSFJpIDwtIHJlYWRPR1IoIk1hcHB5Qml0cy9pLmttbCIpDQojIEVIUmogPC0gcmVhZE9HUigiTWFwcHlCaXRzL2oua21sIikNCiMgRUhSayA8LSByZWFkT0dSKCJNYXBweUJpdHMvay5rbWwiKQ0KIyBFSFJsIDwtIHJlYWRPR1IoIk1hcHB5Qml0cy9sLmttbCIpDQojIA0KIyBvdXRsaW5lX3BvaW50c2EgPC0gRUhSYUBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzDQojIGNvbG5hbWVzKG91dGxpbmVfcG9pbnRzYSkgPC0gYygiWCIsIlkiKQ0KIyBvdXRsaW5lYSA8LSBQb2x5Z29uKG91dGxpbmVfcG9pbnRzYSkNCiMgc3Bfb3V0bGluZWEgPC0gUG9seWdvbnMobGlzdChvdXRsaW5lYSksMSkNCiMgb3V0bGluZV9wb2x5YSA8LSBTcGF0aWFsUG9seWdvbnMobGlzdChzcF9vdXRsaW5lYSkpDQojIHByb2o0c3RyaW5nKG91dGxpbmVfcG9seWEpIDwtIENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQgK2VsbHBzPVdHUzg0IikNCiMgDQojIG91dGxpbmVfcG9pbnRzYiA8LSBFSFJiQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHMNCiMgY29sbmFtZXMob3V0bGluZV9wb2ludHNiKSA8LSBjKCJYIiwiWSIpDQojIG91dGxpbmViIDwtIFBvbHlnb24ob3V0bGluZV9wb2ludHNiKQ0KIyBzcF9vdXRsaW5lYiA8LSBQb2x5Z29ucyhsaXN0KG91dGxpbmViKSwxKQ0KIyBvdXRsaW5lX3BvbHliIDwtIFNwYXRpYWxQb2x5Z29ucyhsaXN0KHNwX291dGxpbmViKSkNCiMgcHJvajRzdHJpbmcob3V0bGluZV9wb2x5YikgPC0gQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCArZWxscHM9V0dTODQiKQ0KIyANCiMgb3V0bGluZV9wb2ludHNjIDwtIEVIUmNAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkcw0KIyBjb2xuYW1lcyhvdXRsaW5lX3BvaW50c2MpIDwtIGMoIlgiLCJZIikNCiMgb3V0bGluZWMgPC0gUG9seWdvbihvdXRsaW5lX3BvaW50c2MpDQojIHNwX291dGxpbmVjIDwtIFBvbHlnb25zKGxpc3Qob3V0bGluZWMpLDEpDQojIG91dGxpbmVfcG9seWMgPC0gU3BhdGlhbFBvbHlnb25zKGxpc3Qoc3Bfb3V0bGluZWMpKQ0KIyBwcm9qNHN0cmluZyhvdXRsaW5lX3BvbHljKSA8LSBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtlbGxwcz1XR1M4NCIpDQojIA0KIyBvdXRsaW5lX3BvaW50c2QgPC0gRUhSZEBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzDQojIGNvbG5hbWVzKG91dGxpbmVfcG9pbnRzZCkgPC0gYygiWCIsIlkiKQ0KIyBvdXRsaW5lZCA8LSBQb2x5Z29uKG91dGxpbmVfcG9pbnRzZCkNCiMgc3Bfb3V0bGluZWQgPC0gUG9seWdvbnMobGlzdChvdXRsaW5lZCksMSkNCiMgb3V0bGluZV9wb2x5ZCA8LSBTcGF0aWFsUG9seWdvbnMobGlzdChzcF9vdXRsaW5lZCkpDQojIHByb2o0c3RyaW5nKG91dGxpbmVfcG9seWQpIDwtIENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQgK2VsbHBzPVdHUzg0IikNCiMgDQojIG91dGxpbmVfcG9pbnRzZSA8LSBFSFJlQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHMNCiMgY29sbmFtZXMob3V0bGluZV9wb2ludHNlKSA8LSBjKCJYIiwiWSIpDQojIG91dGxpbmVlIDwtIFBvbHlnb24ob3V0bGluZV9wb2ludHNlKQ0KIyBzcF9vdXRsaW5lZSA8LSBQb2x5Z29ucyhsaXN0KG91dGxpbmVlKSwxKQ0KIyBvdXRsaW5lX3BvbHllIDwtIFNwYXRpYWxQb2x5Z29ucyhsaXN0KHNwX291dGxpbmVlKSkNCiMgcHJvajRzdHJpbmcob3V0bGluZV9wb2x5ZSkgPC0gQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCArZWxscHM9V0dTODQiKQ0KIyANCiMgb3V0bGluZV9wb2ludHNmIDwtIEVIUmZAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkcw0KIyBjb2xuYW1lcyhvdXRsaW5lX3BvaW50c2YpIDwtIGMoIlgiLCJZIikNCiMgb3V0bGluZWYgPC0gUG9seWdvbihvdXRsaW5lX3BvaW50c2YpDQojIHNwX291dGxpbmVmIDwtIFBvbHlnb25zKGxpc3Qob3V0bGluZWYpLDEpDQojIG91dGxpbmVfcG9seWYgPC0gU3BhdGlhbFBvbHlnb25zKGxpc3Qoc3Bfb3V0bGluZWYpKQ0KIyBwcm9qNHN0cmluZyhvdXRsaW5lX3BvbHlmKSA8LSBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtlbGxwcz1XR1M4NCIpDQojIA0KIyBvdXRsaW5lX3BvaW50c2cgPC0gRUhSZ0Bwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzDQojIGNvbG5hbWVzKG91dGxpbmVfcG9pbnRzZykgPC0gYygiWCIsIlkiKQ0KIyBvdXRsaW5lZyA8LSBQb2x5Z29uKG91dGxpbmVfcG9pbnRzZykNCiMgc3Bfb3V0bGluZWcgPC0gUG9seWdvbnMobGlzdChvdXRsaW5lZyksMSkNCiMgb3V0bGluZV9wb2x5ZyA8LSBTcGF0aWFsUG9seWdvbnMobGlzdChzcF9vdXRsaW5lZykpDQojIHByb2o0c3RyaW5nKG91dGxpbmVfcG9seWcpIDwtIENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQgK2VsbHBzPVdHUzg0IikNCiMgDQojIG91dGxpbmVfcG9pbnRzaCA8LSBFSFJoQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHMNCiMgY29sbmFtZXMob3V0bGluZV9wb2ludHNoKSA8LSBjKCJYIiwiWSIpDQojIG91dGxpbmVoIDwtIFBvbHlnb24ob3V0bGluZV9wb2ludHNoKQ0KIyBzcF9vdXRsaW5laCA8LSBQb2x5Z29ucyhsaXN0KG91dGxpbmVoKSwxKQ0KIyBvdXRsaW5lX3BvbHloIDwtIFNwYXRpYWxQb2x5Z29ucyhsaXN0KHNwX291dGxpbmVoKSkNCiMgcHJvajRzdHJpbmcob3V0bGluZV9wb2x5aCkgPC0gQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCArZWxscHM9V0dTODQiKQ0KIyANCiMgb3V0bGluZV9wb2ludHNpIDwtIEVIUmlAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkcw0KIyBjb2xuYW1lcyhvdXRsaW5lX3BvaW50c2kpIDwtIGMoIlgiLCJZIikNCiMgb3V0bGluZWkgPC0gUG9seWdvbihvdXRsaW5lX3BvaW50c2kpDQojIHNwX291dGxpbmVpIDwtIFBvbHlnb25zKGxpc3Qob3V0bGluZWkpLDEpDQojIG91dGxpbmVfcG9seWkgPC0gU3BhdGlhbFBvbHlnb25zKGxpc3Qoc3Bfb3V0bGluZWkpKQ0KIyBwcm9qNHN0cmluZyhvdXRsaW5lX3BvbHlpKSA8LSBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtlbGxwcz1XR1M4NCIpDQojIA0KIyBvdXRsaW5lX3BvaW50c2ogPC0gRUhSakBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzDQojIGNvbG5hbWVzKG91dGxpbmVfcG9pbnRzaikgPC0gYygiWCIsIlkiKQ0KIyBvdXRsaW5laiA8LSBQb2x5Z29uKG91dGxpbmVfcG9pbnRzaikNCiMgc3Bfb3V0bGluZWogPC0gUG9seWdvbnMobGlzdChvdXRsaW5laiksMSkNCiMgb3V0bGluZV9wb2x5aiA8LSBTcGF0aWFsUG9seWdvbnMobGlzdChzcF9vdXRsaW5laikpDQojIHByb2o0c3RyaW5nKG91dGxpbmVfcG9seWopIDwtIENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQgK2VsbHBzPVdHUzg0IikNCiMgDQojIG91dGxpbmVfcG9pbnRzayA8LSBFSFJrQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHMNCiMgY29sbmFtZXMob3V0bGluZV9wb2ludHNrKSA8LSBjKCJYIiwiWSIpDQojIG91dGxpbmVrIDwtIFBvbHlnb24ob3V0bGluZV9wb2ludHNrKQ0KIyBzcF9vdXRsaW5layA8LSBQb2x5Z29ucyhsaXN0KG91dGxpbmVrKSwxKQ0KIyBvdXRsaW5lX3BvbHlrIDwtIFNwYXRpYWxQb2x5Z29ucyhsaXN0KHNwX291dGxpbmVrKSkNCiMgcHJvajRzdHJpbmcob3V0bGluZV9wb2x5aykgPC0gQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCArZWxscHM9V0dTODQiKQ0KIyANCiMgb3V0bGluZV9wb2ludHNsIDwtIEVIUmxAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkcw0KIyBjb2xuYW1lcyhvdXRsaW5lX3BvaW50c2wpIDwtIGMoIlgiLCJZIikNCiMgb3V0bGluZWwgPC0gUG9seWdvbihvdXRsaW5lX3BvaW50c2wpDQojIHNwX291dGxpbmVsIDwtIFBvbHlnb25zKGxpc3Qob3V0bGluZWwpLDEpDQojIG91dGxpbmVfcG9seWwgPC0gU3BhdGlhbFBvbHlnb25zKGxpc3Qoc3Bfb3V0bGluZWwpKQ0KIyBwcm9qNHN0cmluZyhvdXRsaW5lX3BvbHlsKSA8LSBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtlbGxwcz1XR1M4NCIpDQpgYGANCg0KDQpgYGB7ciBTdGF0aWMgbWFwLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBzdGF0ZSA8LSBtYXBfZGF0YSgic3RhdGUiKQ0KIyBjb3VudHkgPC0gbWFwX2RhdGEoImNvdW50eSIpDQojIA0KIyANCiMgdG4gPC0gY291bnR5ICU+JQ0KIyAgIGZpbHRlcihyZWdpb249PSJ0ZW5uZXNzZWUiKQ0KIyBreSA8LSBjb3VudHkgJT4lDQojICAgZmlsdGVyKHJlZ2lvbj09ImtlbnR1Y2t5IikNCiMgYWwgPC0gY291bnR5ICU+JQ0KIyAgIGZpbHRlcihyZWdpb249PSJhbGFiYW1hIikNCg0KDQojIGdncGxvdCgpICsNCiMgICBnZW9tX3BvbHlnb24oZGF0YSA9IHN0YXRlLCBhZXMoeD1sb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yPSJibGFjayIpICsNCiMgICBnZW9tX3BvbHlnb24oZGF0YSA9IHRuLCBhZXMoeD1sb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yPSJibGFjayIpICsNCiMgICBnZW9tX3BvbHlnb24oZGF0YSA9IGt5LCBhZXMoeD1sb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yPSJibGFjayIpICsNCiMgICBnZW9tX3BvbHlnb24oZGF0YSA9IGFsLCBhZXMoeD1sb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yPSJibGFjayIpICsNCiMgICBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlhLCBhZXMoeD1vdXRsaW5lX3BvbHlhQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5YUBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQojICAgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiMgICBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHliLCBhZXMoeD1vdXRsaW5lX3BvbHliQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5YkBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQojICAgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiMgICBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHljLCBhZXMoeD1vdXRsaW5lX3BvbHljQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5Y0Bwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlkLCBhZXMoeD1vdXRsaW5lX3BvbHlkQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5ZEBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHllLCBhZXMoeD1vdXRsaW5lX3BvbHllQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5ZUBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlmLCBhZXMoeD1vdXRsaW5lX3BvbHlmQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5ZkBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlnLCBhZXMoeD1vdXRsaW5lX3BvbHlnQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5Z0Bwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHloLCBhZXMoeD1vdXRsaW5lX3BvbHloQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5aEBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlpLCBhZXMoeD1vdXRsaW5lX3BvbHlpQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5aUBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlqLCBhZXMoeD1vdXRsaW5lX3BvbHlqQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5akBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlrLCBhZXMoeD1vdXRsaW5lX3BvbHlrQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5a0Bwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1vdXRsaW5lX3BvbHlsLCBhZXMoeD1vdXRsaW5lX3BvbHlsQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLA0KICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk9b3V0bGluZV9wb2x5bEBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSksDQogICMgICAgICAgICAgICAgIGFscGhhID0gLjgsIGZpbGw9Im9yYW5nZSIpICsNCiAgIyBnZW9tX3BvaW50KGRhdGEgPSBzaXRlX3BvaW50cywgYWVzKHg9TG9uZ2l0dWRlLHk9TGF0aXR1ZGUpLCBjb2xvcj0iYmxhY2siKSArDQogICMgIyBjb29yZF9maXhlZCh4bGltID0gYygtOTAuNSwgLTgyKSwgIHlsaW0gPSBjKDM0LjUsIDM3LjYpLCByYXRpbyA9IDEuMikgKw0KICAjIHhsYWIoIkxvbmdpdHVkZSIpICsgeWxhYigiTGF0aXR1ZGUiKSArIGdndGl0bGUoIkVhc3Rlcm4gSGlnaGxhbmQgUmltIHN1YnNldCAoZ29sZCkgYW5kIHN0dWR5IHNpdGVzIikNCg0KIyBnZW9tX21hcChkYXRhID0gZGF0YSwgbWFwID0gbWFwLCBhZXMobWFwX2lkID0gY291bnRyaWVzLCBmaWxsID0gY29sb3IpKSANCmBgYA0KDQpgYGB7ciBMb29wIG1hZ2ljLCBjYWNoZT1UUlVFLCBpbmNsdWRlPUZBTFNFfQ0Kc2l0ZXNfc3ViPC11bmlxdWUoc3BweHNpdGVzJElEKQ0Kc3BwX3N1YjwtdW5pcXVlKHNwcHhzaXRlcyRTcGVjaWVzKQ0KDQojTWFrZSBhIG1hdHJpeCB3aXRoIGxvb3AgZnVuY3Rpb24NCnNwcF9jb21tYXQgPC0gbWF0cml4KDAsIGxlbmd0aChzaXRlc19zdWIpLCBsZW5ndGgoc3BwX3N1YikpDQpmb3IgKGkgaW4gMTpucm93KHNwcF9jb21tYXQpKXt0ZW1wX3NpdGVzIDwtIHNwcHhzaXRlc1t3aGljaChzcHB4c2l0ZXMkSUQgPT0gc2l0ZXNfc3ViW2ldKSxdDQogIHNwcF9jb21tYXRbaSwgd2hpY2goc3BwX3N1YiVpbiV0ZW1wX3NpdGVzJFNwZWNpZXMpXTwtIDENCiAgcHJpbnQoaSl9DQoNCiNOYW1lIHJvd3MgYW5kIENvbHVtbnMNCnJvd25hbWVzKHNwcF9jb21tYXQpIDwtIGFzLmNoYXJhY3RlcihzaXRlc19zdWIpDQpjb2xuYW1lcyhzcHBfY29tbWF0KSA8LSBhcy5jaGFyYWN0ZXIoc3BwX3N1YikNCg0KI0NoYW5nZSBtYXRyaXggaW50byBkYXRhZnJhbWUNCnNwcF9jb21tYXQuZGY8LSBhcy5kYXRhLmZyYW1lKHNwcF9jb21tYXQpDQoNCiNNYWtlIGVtcHR5IHF1YWRyYXRzIHRydWx5IGVtcHR5DQpzcHBfY29tbWF0LmRmLmZpeGVkPC1zdWJzZXQoc3BwX2NvbW1hdC5kZiwgc2VsZWN0PS1jKEVNUFRZKSkNCg0KI0FkZCBzaXRlIGNvbHVtbiBiYWNrIGluIGFuZCBjaGFuZ2UgaXRzIG5hbWUNCkFsbFBvbmRzIDwtIGNiaW5kKHNpdGVuYW1lcyRQb25kLHNwcF9jb21tYXQuZGYuZml4ZWQpDQpuYW1lcyhBbGxQb25kcylbbmFtZXMoQWxsUG9uZHMpPT0ic2l0ZW5hbWVzJFBvbmQiXSA8LSAiU2l0ZSINCg0KYmVlcChzb3VuZCA9IDEsIGV4cHIgPSBOVUxMKQ0KYGBgDQoNCmBgYHtyIFNwbGl0IHNpdGVzLCBpbmNsdWRlPUZBTFNFfQ0KI0JyZWFrIHVwIEFsbFBvbmRzIGludG8gZGF0YWZyYW1lcyBieSBzaXRlDQojVGhlIGZpcnN0IGNvbHVtbiBoYXMgdG8gYmUgcmVtb3ZlZCBmb3IgZWFjaA0KI1RyYW5zcG9zZSB0aGUgZGF0YWZyYW1lcyBzbyBzcGVjaWVzIGFyZSBjb2x1bW5zDQoNClMwMTwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDEpLCAtMSkpDQpTMDI8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSAyKSwgLTEpKQ0KUzAzPC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gMyksIC0xKSkNClMwNDwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDQpLCAtMSkpDQpTMDU8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSA1KSwgLTEpKQ0KUzA2PC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gNiksIC0xKSkNClMwNzwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDcpLCAtMSkpDQpTMDg8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSA4KSwgLTEpKQ0KUzA5PC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gOSksIC0xKSkNClMxMDwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDEwKSwgLTEpKQ0KUzExPC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gMTEpLCAtMSkpDQpTMTI8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSAxMiksIC0xKSkNClMxMzwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDEzKSwgLTEpKQ0KUzE0PC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gMTQpLCAtMSkpDQpTMTY8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSAxNiksIC0xKSkNClMxNzwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDE3KSwgLTEpKQ0KUzE4PC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gMTgpLCAtMSkpDQpTMTk8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSAxOSksIC0xKSkNClMyMDwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDIwKSwgLTEpKQ0KUzIxPC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gMjEpLCAtMSkpDQpTMjI8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSAyMiksIC0xKSkNClMyMzwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDIzKSwgLTEpKQ0KUzI0PC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gMjQpLCAtMSkpDQpTMjU8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSAyNSksIC0xKSkNClMyNjwtdChzZWxlY3QoZmlsdGVyKEFsbFBvbmRzLCBTaXRlID09IDI2KSwgLTEpKQ0KUzI3PC10KHNlbGVjdChmaWx0ZXIoQWxsUG9uZHMsIFNpdGUgPT0gMjcpLCAtMSkpDQpTMjg8LXQoc2VsZWN0KGZpbHRlcihBbGxQb25kcywgU2l0ZSA9PSAyOCksIC0xKSkNCmBgYA0KDQpgYGB7ciBVbmljb3JuIHZvbWl0IHByZXAsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBjYWNoZT1UUlVFLCBpbmNsdWRlPUZBTFNFfQ0KI01ha2UgYSBsaXN0IG9mIGFsbCBzaXRlIGRhdGFmcmFtZXMNCnNpdGUubGlzdC5hbGwgPSBsaXN0KFMwMT1TMDEsUzAyPVMwMixTMDM9UzAzLFMwND1TMDQsUzA1PVMwNSxTMDY9UzA2LFMwNz1TMDcsUzA4PVMwOCxTMDk9UzA5LFMxMD1TMTAsUzExPVMxMSxTMTI9UzEyLFMxMz1TMTMsUzE0PVMxNCxTMTY9UzE2LFMxNz1TMTcsUzE4PVMxOCxTMTk9UzE5LFMyMD1TMjAsUzIxPVMyMSxTMjI9UzIyLFMyMz1TMjMsUzI0PVMyNCxTMjU9UzI1LFMyNj1TMjYsUzI3PVMyNyxTMjg9UzI4KQ0KI0NvbnZlcnQgZXZlcnl0aGluZyBpbiBsaXN0IHRvIGluY2lkZW5jZSBmcmVxdWVuY2llcw0Kc2l0ZS5saXN0LmZyZXEuYWxsID0gbGFwcGx5KHNpdGUubGlzdC5hbGwsIGFzLmluY2ZyZXEpDQpgYGANCg0KYGBge3IgVW5pY29ybiB2b21pdCBwcmVwMiwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUUsIGluY2x1ZGU9RkFMU0V9DQpvdXQuaW5jLmFsbDwtaU5FWFQoc2l0ZS5saXN0LmZyZXEuYWxsLCBxPTAsIGRhdGF0eXBlPSJpbmNpZGVuY2VfZnJlcSIsIG5ib290PTEwMDApDQpiZWVwKHNvdW5kID0gMSwgZXhwciA9IE5VTEwpDQpgYGANCg0KYGBge3IgS2FibGUgMiwgaW5jbHVkZT1GQUxTRX0NCiNUaGUgaU5FWFQgb3V0cHV0ICgib3V0LmluYy5hbGwiKSBjb250YWlucyB0aHJlZSB0YWJsZXM7ICJBc3lFc3QiIGhhcyBhbGwgdGhlIGRhdGEgd2UgbmVlZA0KI1NhdmVkIGl0IGFzIGFuIG9iamVjdCBhbmQgY2hhbmdlZCBpdCBzbyBpdCB3b3VsZCBiZSBtb3JlIHJlYWRhYmxlDQpSaWNoRGl2PC1vdXQuaW5jLmFsbCRBc3lFc3QNClJpY2hEaXZUPC1zdWJzZXQoUmljaERpdiwgc2VsZWN0PS1jKHMuZS4sIExDTCwgVUNMKSkNClJpY2hEaXZPYnM8LXN1YnNldChzcHJlYWQoUmljaERpdlQsIERpdmVyc2l0eSwgT2JzZXJ2ZWQpLCBzZWxlY3Q9LWMoRXN0aW1hdG9yKSkNClJpY2hEaXZFc3Q8LXN1YnNldChzcHJlYWQoUmljaERpdlQsIERpdmVyc2l0eSwgRXN0aW1hdG9yKSwgc2VsZWN0PS1jKE9ic2VydmVkKSkNCg0KI1RyaW0gZG93biBjb2x1bW4gbmFtZXMgc28gdGhleSBkb24ndCBzdWNrDQpuYW1lcyhSaWNoRGl2T2JzKTwtYygiU2l0ZSIsICJSaWNobmVzc09icyIsICJTaGFubm9uT2JzIiwgIlNpbXBzb25PYnMiKQ0KbmFtZXMoUmljaERpdkVzdCk8LWMoIlNpdGUiLCAiUmljaG5lc3NFeHAiLCAiU2hhbm5vbkV4cCIsICJTaW1wc29uRXhwIikNCg0KI0NvbGxhcHNlIHNpdGVzOyBoYXZlIHRvIGRvIGZ1bmt5IHRoaW5ncyB0byBkZWFsIHdpdGggTkFzDQpjb21wcmVzcyA8LSBmdW5jdGlvbih4KSBjKG5hLm9taXQoeCksIE5BKVsxXQ0KUmljaERpdk9icy4xPC1hZ2dyZWdhdGUoUmljaERpdk9ic1syOjRdLCBSaWNoRGl2T2JzWzFdLCBjb21wcmVzcykNClJpY2hEaXZFc3QuMTwtYWdncmVnYXRlKFJpY2hEaXZFc3RbMjo0XSwgUmljaERpdkVzdFsxXSwgY29tcHJlc3MpDQoNCiNSZW1vdmUgc2l0ZSBjb2x1bW4gZnJvbSBSaWNoRGl2RXN0IHNvIGl0J3Mgbm90IGR1cGxpY2F0ZWQgd2hlbiBtZXJnaW5nDQpSaWNoRGl2RXN0LjI8LXN1YnNldChSaWNoRGl2RXN0LjEsIHNlbGVjdD0tYyhTaXRlKSkNCg0KI01lcmdlIGV2ZXJ5Ym9keSB0b2dldGhlcg0KUmljaERpdkZpbmFsPC1jYmluZChSaWNoRGl2T2JzLjEsIFJpY2hEaXZFc3QuMikNCg0KI1Jlb3JkZXIgY29sdW1ucyBzbyB0aGV5IG1ha2Ugc2Vuc2UNClJpY2hEaXZUYWI8LVJpY2hEaXZGaW5hbFssYygxLDIsNSwzLDYsNCw3KV0NClJpY2hEaXZUYWIkRG9taW5hbmNlPC0xLyhSaWNoRGl2VGFiJFNpbXBzb25PYnMpDQpSaWNoRGl2S2FiPC1SaWNoRGl2VGFiW2MoMSwgNiwgNywgOCwgMTAsIDI2LCAyNyksXQ0KDQprYWJsZShSaWNoRGl2S2FiWzE6NyxdLCBmb3JtYXQgPSAicGFuZG9jIiwgZnVsbF93aWR0aD1GLCBjYXB0aW9uID0gJ1RhYmxlIDIuIE9ic2VydmVkIGFuZCBleHBlY3RlZCBIaWxsIG51bWJlcnMgZnJvbSBhIHBvcnRpb24gb2YgdGhlIHNpdGVzLicpDQpgYGANCg0KYGBge3IgRXN0IGFuZCBPYnMgUmljaG5lc3MsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTEwLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KUmljaG5lc3NPbmx5PC1maWx0ZXIoUmljaERpdiwgRGl2ZXJzaXR5ID09ICJTcGVjaWVzIHJpY2huZXNzIikNCmNvbG5hbWVzKFJpY2huZXNzT25seSlbY29sbmFtZXMoUmljaG5lc3NPbmx5KT09IkxDTCJdIDwtICJSaWNoTENMIg0KY29sbmFtZXMoUmljaG5lc3NPbmx5KVtjb2xuYW1lcyhSaWNobmVzc09ubHkpPT0iVUNMIl0gPC0gIlJpY2hVQ0wiDQpjb2xuYW1lcyhSaWNobmVzc09ubHkpW2NvbG5hbWVzKFJpY2huZXNzT25seSk9PSJFc3RpbWF0b3IiXSA8LSAiRXN0aW1hdGVkIg0KUmljaEdhdGg8LWdhdGhlcihSaWNobmVzc09ubHksUmljaG5lc3MsdmFsdWUsT2JzZXJ2ZWQ6RXN0aW1hdGVkKQ0KUmljaFNpemU8LSBjYmluZChSaWNoR2F0aCwgc2l0ZXNpemVzJFF1YWRyYXRzKQ0KY29sbmFtZXMoUmljaFNpemUpW2NvbG5hbWVzKFJpY2hTaXplKT09InNpdGVzaXplcyRRdWFkcmF0cyJdIDwtICJRdWFkcmF0cyINCmBgYA0KDQpgYGB7ciBTbWFsbGVyIGN1cnZlcyAxLCBpbmNsdWRlPUZBTFNFfQ0KI0xpc3QgdGhlIGRhdGFmcmFtZXMsIHRoZW4gY29udmVydCB0aGVtIGludG8gaW5jaWRlbmNlIGZyZXF1ZW5jaWVzDQojSSBicm9rZSB0aGVtIGludG8gbWFuYWdlYWJsZSBjaHVua3MgdGhhdCBncmFwaCBtb3JlIGNsZWFybHkgdGhhbiBldmVyeXRoaW5nIGF0IG9uY2UNCg0Kc2l0ZS5saXN0LjEgPSBsaXN0KFMwMz1TMDMsIFMwOD1TMDgsICBTMDk9UzA5LCBTMjg9UzI4KQ0Kc2l0ZS5saXN0LmZyZXEuMSA9IGxhcHBseShzaXRlLmxpc3QuMSwgYXMuaW5jZnJlcSkNCg0Kc2l0ZS5saXN0LjIgPSBsaXN0KFMwMT1TMDEsIFMwMj1TMDIsICBTMTE9UzExLCBTMjc9UzI3KQ0Kc2l0ZS5saXN0LmZyZXEuMiA9IGxhcHBseShzaXRlLmxpc3QuMiwgYXMuaW5jZnJlcSkNCg0Kc2l0ZS5saXN0LjMgPSBsaXN0KFMxMD1TMTAsIFMxMz1TMTMsIFMxND1TMTQsIFMyMz1TMjMpDQpzaXRlLmxpc3QuZnJlcS4zID0gbGFwcGx5KHNpdGUubGlzdC4zLCBhcy5pbmNmcmVxKQ0KDQoNCnNpdGUubGlzdC40ID0gbGlzdChTMDU9UzA1LFMxMj1TMTIsIFMxNz1TMTcpDQpzaXRlLmxpc3QuZnJlcS40ID0gbGFwcGx5KHNpdGUubGlzdC40LCBhcy5pbmNmcmVxKQ0KDQpzaXRlLmxpc3QuNSA9IGxpc3QoIFMxOT1TMTksIFMyMD1TMjAsIFMyMT1TMjEsIFMyNT1TMjUpDQpzaXRlLmxpc3QuZnJlcS41ID0gbGFwcGx5KHNpdGUubGlzdC41LCBhcy5pbmNmcmVxKQ0KDQpzaXRlLmxpc3QuNiA9IGxpc3QoUzA2PVMwNiwgUzE2PVMxNiwgUzIyPVMyMiwgUzI2PVMyNikNCnNpdGUubGlzdC5mcmVxLjYgPSBsYXBwbHkoc2l0ZS5saXN0LjYsIGFzLmluY2ZyZXEpDQoNCnNpdGUubGlzdC43ID0gbGlzdChTMDQ9UzA0LCBTMDc9UzA3LCBTMTg9UzE4LCBTMjQ9UzI0KQ0Kc2l0ZS5saXN0LmZyZXEuNyA9IGxhcHBseShzaXRlLmxpc3QuNywgYXMuaW5jZnJlcSkNCmBgYA0KDQoNCiANCmBgYHtyIERhdGEgcmVhcnJhbmdpbmcsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTEwLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KSW50ZXJ2YWxzPC1zZWxlY3Qoc2xpY2UoUmljaEdhdGgsIGMoMjg6NTQpKSwgYyhSaWNoTENMLCBSaWNoVUNMKSkNClJpY2hJbnRzPC1jYmluZChSaWNoRGl2VGFiLCBJbnRlcnZhbHMpDQpSaWNoSW50cyRQZXJjQ29tcGxldGUgPC0gUmljaEludHMkUmljaG5lc3NPYnMvUmljaEludHMkUmljaG5lc3NFeHAqMTAwDQpSaWNoSW50cyRQZXJjQ29tcGxldGVVPC0gUmljaEludHMkUmljaG5lc3NPYnMvUmljaEludHMkUmljaFVDTCoxMDANClJpY2hJbnRzJFBlcmNDb21wbGV0ZUw8LSBSaWNoSW50cyRSaWNobmVzc09icy9SaWNoSW50cyRSaWNoTENMKjEwMA0Kc2l0ZXNpemVzJFF1YWRzQXJlYTwtIHNpdGVzaXplcyRRdWFkcmF0cy8ocGkqKHNpdGVzaXplcyRMZW5ndGheMikpDQpzaXRlc2l6ZXMkQXJlYTwtKHBpKihzaXRlc2l6ZXMkTGVuZ3RoXjIpKQ0KIyANCiMgVEhJUyBQTE9UIElTIFRSQVNIDQojIGdncGxvdChSaWNoSW50cywgYWVzKHg9U2l0ZSwgeT1QZXJjQ29tcGxldGUpKSArDQojICAgZ2VvbV9iYXIoYWVzKHk9c2l0ZXNpemVzJFF1YWRyYXRzLHg9U2l0ZSksIHN0YXQ9ImlkZW50aXR5Iiwgd2lkdGggPSAwLjc1LCBmaWxsPSJsaWdodGdyZXkiKSsNCiMgICBnZW9tX3BvaW50KHNpemU9MikrDQojICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1QZXJjQ29tcGxldGVMLCB5bWF4PVBlcmNDb21wbGV0ZVUpLCB3aWR0aD0uMykgKw0KIyAgIHlsYWIoIk9ic2VydmVkL0V4cGVjdGVkIFJpY2huZXNzICogMTAwIikrDQojICAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofi4sIG5hbWUgPSAiUXVhZHJhdHMgU2FtcGxlZCIpKSsNCiMgICBnZ3RpdGxlKCJDb21wbGV0aW9uIHBlcmNlbnRhZ2UgYW5kIHNhbXBsZSBzaXplIHBlciBzaXRlIikrDQojICAgdGhlbWUoYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNCksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpDQpgYGANCg0KYGBge3IgTE0gU2FtcGxpbmcgc3VmZmljaWVuY3ksIGluY2x1ZGU9RkFMU0V9DQpsbVJpY2hRdWFkIDwtIGxtKFJpY2hJbnRzJFBlcmNDb21wbGV0ZSB+IHNpdGVzaXplcyRRdWFkc0FyZWEpDQphdXRvcGxvdChsbVJpY2hRdWFkKQ0KYVJpY2hRdWFkPC1hbm92YShsbVJpY2hRdWFkKQ0KYVJpY2hRdWFkDQpgYGANCg0KYGBge3IgU2l0ZSBzaXplIGFuZCByaWNobmVzcywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnF1YWRkaWVzPC1tZXJnZShzaXRlc2l6ZXMsIFJpY2hJbnRzLCBieT0iU2l0ZSIpDQpxdWFkZGllcyRMYXRpdHVkZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihxdWFkZGllcyRMYXRpdHVkZSkpDQpgYGANCg0KYGBge3IgU29yZW5zZW4gdGltZSwgaW5jbHVkZT1GQUxTRX0NCnN1bTAxPC1yb3dTdW1zKFMwMSkNCnN1bTAyPC1yb3dTdW1zKFMwMikNCnN1bTAzPC1yb3dTdW1zKFMwMykNCnN1bTA0PC1yb3dTdW1zKFMwNCkNCnN1bTA1PC1yb3dTdW1zKFMwNSkNCnN1bTA2PC1yb3dTdW1zKFMwNikNCnN1bTA3PC1yb3dTdW1zKFMwNykNCnN1bTA4PC1yb3dTdW1zKFMwOCkNCnN1bTA5PC1yb3dTdW1zKFMwOSkNCnN1bTEwPC1yb3dTdW1zKFMxMCkNCnN1bTExPC1yb3dTdW1zKFMxMSkNCnN1bTEyPC1yb3dTdW1zKFMxMikNCnN1bTEzPC1yb3dTdW1zKFMxMykNCnN1bTE0PC1yb3dTdW1zKFMxNCkNCnN1bTE2PC1yb3dTdW1zKFMxNikNCnN1bTE3PC1yb3dTdW1zKFMxNykNCnN1bTE4PC1yb3dTdW1zKFMxOCkNCnN1bTE5PC1yb3dTdW1zKFMxOSkNCnN1bTIwPC1yb3dTdW1zKFMyMCkNCnN1bTIxPC1yb3dTdW1zKFMyMSkNCnN1bTIyPC1yb3dTdW1zKFMyMikNCnN1bTIzPC1yb3dTdW1zKFMyMykNCnN1bTI0PC1yb3dTdW1zKFMyNCkNCnN1bTI1PC1yb3dTdW1zKFMyNSkNCnN1bTI2PC1yb3dTdW1zKFMyNikNCnN1bTI3PC1yb3dTdW1zKFMyNykNCnN1bTI4PC1yb3dTdW1zKFMyOCkNCg0Kc3VtbWFyeTwtYXMuZGF0YS5mcmFtZShyYmluZChzdW0wMSwgc3VtMDIsIHN1bTAzLCBzdW0wNCwgc3VtMDUsIHN1bTA2LCBzdW0wNywgc3VtMDgsIHN1bTA5LCBzdW0xMCwgc3VtMTEsIHN1bTEyLCBzdW0xMywgc3VtMTQsIHN1bTE2LCBzdW0xNywgc3VtMTgsIHN1bTE5LCBzdW0yMCwgc3VtMjEsIHN1bTIyLCBzdW0yMywgc3VtMjQsIHN1bTI1LCBzdW0yNiwgc3VtMjcsIHN1bTI4KSkNCnN1bXM8LWNvbFN1bXMoc3VtbWFyeSkNCiNUTyBERUxFVEUgU0lOR0xFVE9OUw0Kc3Vtc3VtczwtcmJpbmQoc3Vtcywgc3VtbWFyeSkNCnJvd25hbWVzKHN1bXN1bXMpWzFdPC0ic3VtIg0Kc3Vtc3VtczEgPSBzdW1zdW1zWyxzdW1zID4gMV0NCm5jb2woc3Vtc3Vtc1ssc3VtcyA9PSAxXSkNCiMxMDQgc2luZ2xldG9ucyENCm5jb2woc3Vtc3Vtc1ssc3VtcyA9PSAyXSkNCiM0MiBkb3VibGV0b25zIQ0KDQojU2luZ2xldG9ucyBBTkQgZG91YmxldG9ucyBmb3IgdGhpcyBiYWQgYm95DQpzdW1zdW1zW3N1bXN1bXMgPiAwXSA8LSAxDQpzdW1zdW1zMzwtc2xpY2Uoc3Vtc3VtcywgLWMoMSkpDQoNCiNDb252ZXJ0IHRvIGJpbmFyeQ0Kc3Vtc3VtczFbc3Vtc3VtczEgPiAwXSA8LSAxDQoNCnN1bXN1bXMyPC1zbGljZShzdW1zdW1zMSwgLWMoMSkpDQoNCiMwPWlkZW50aWNhbCwgMT10aGUgbW9zdCBkaXNzaW1pbGFyDQpzb3JlbnNlbjwtdmVnZGlzdChzdW1zdW1zMiwgbWV0aG9kPSJicmF5IiwgYmluYXJ5PVRSVUUsIGRpYWc9VFJVRSwgdXBwZXI9RkFMU0UsIG5hLnJtID0gRkFMU0UpDQpzb3JlbnNlbi5tPC1hcy5tYXRyaXgoc29yZW5zZW4pDQpzb3JlbnNlbi5tLnQ8LXNpZ25pZihzb3JlbnNlbi5tLCBkaWdpdHMgPSAzKQ0KYGBgDQoNCmBgYHtyIERpc3RhbmNlIE1hdHJpeCwgaW5jbHVkZT1GQUxTRX0NCnNpdGVzaXplc2dlbzwtc2VsZWN0KHNpdGVzaXplcywgYygiU2l0ZSIsICJMYXRpdHVkZSIsICJMb25naXR1ZGUiKSkNCnNpdGVzaXplc2dlby4xPC1zaXRlc2l6ZXNnZW9bLGMoMSwzLDIpXQ0Kc2l0ZXNpemVzZ2VvLjI8LXNpdGVzaXplc2dlby4xWyxjKDIsMyldDQpkaXN0YW5jZS5tPC1kaXN0bShzaXRlc2l6ZXNnZW8uMikNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI1RoaXMgaXMgcmVhbGx5IHNsb3BweQ0Kc29yZW5zZW5jb2w8LWFzLmRhdGEuZnJhbWUoc29yZW5zZW4ubS50KQ0KZGlzdGFuY2Vjb2w8LWFzLmRhdGEuZnJhbWUoZGlzdGFuY2UubSkNCnNvcmVuc2VubWVsdDwtbWVsdChzb3JlbnNlbmNvbCwgdmFyaWFibGUubmFtZSA9ICdTb3JlbnNlbicpDQpnZW9ncmFwaGljbWVsdDwtbWVsdChkaXN0YW5jZWNvbCwgdmFyaWFibGUubmFtZSA9ICdHZW9ncmFwaGljJykNCmRpc3RhbmNlLjE8LWNiaW5kKGdlb2dyYXBoaWNtZWx0LCBzb3JlbnNlbm1lbHQpDQpuYW1lcyhkaXN0YW5jZS4xKTwtYygiVmFyMSIsICJnZW9ncmFwaGljIiwgIlZhcjIiLCAiU29yZW5zZW4iKQ0KI1JlbW92ZSB6ZXJvJ3MgYmVjYXVzZSB0aGV5IG9jY3VyIHdod2VyZSBzaXRlcyBtYXRjaA0KZGlzdGFuY2UuZjwtZmlsdGVyKGRpc3RhbmNlLjEsIGdlb2dyYXBoaWMgPiAwKQ0KYGBgDQoNCmBgYHtyIE5NRFMgcHJlcCwgaW5jbHVkZT1GQUxTRX0NCiMgc29yZW5zZW4ubm1kczAxIDwtIG1ldGFNRFMoc29yZW5zZW4sIGs9MTApDQojIHNvcnN0cmVzc3Bsb3Q8LXN0cmVzc3Bsb3Qoc29yZW5zZW4ubm1kczAxKQ0KIyANCiMgYmVlcChzb3VuZCA9IDEsIGV4cHIgPSBOVUxMKQ0KYGBgDQoNCmBgYHtyIERlYXRoIHRvIHNpbmdsZXRvbnN9DQpBbGxQb25kc05vU2l0ZTwtc2VsZWN0KEFsbFBvbmRzLCAtMSkNCkFsbFN1bXM8LWNvbFN1bXMoQWxsUG9uZHNOb1NpdGUpDQpBbGxEYXRhPC1yYmluZChBbGxQb25kc05vU2l0ZSwgQWxsU3VtcykNCnJvd25hbWVzKEFsbERhdGEpW3Jvd25hbWVzKEFsbERhdGEpPT0iMTAzMiJdIDwtICJzdW0iDQojUmVtb3ZlIGRvdWJsdGVvbnMNCkFsbERhdGFTdW1zID0gQWxsRGF0YVssQWxsU3VtcyA+IDFdDQpuY29sKEFsbERhdGFbLHN1bXMgPDNdKQ0KIzIzNSoqIHNpbmdsZXRvbnMhDQojMTUyIHNpbmdsdG9ucyBhbmQgZG91YmxldG9ucyENCg0KQWxsRGF0YU5vU2luZzwtc2xpY2UoQWxsRGF0YVN1bXMsIC1jKDEwMzIpKQ0KQWxsRGF0YU5vU2luZyRzdW08LXJvd1N1bXMoQWxsRGF0YU5vU2luZykNCkFsbERhdGFOb1NpbmdaZXJvPC1maWx0ZXIoQWxsRGF0YU5vU2luZywgc3VtID4gMCkNCmBgYA0KDQpgYGB7ciBTb3JlbnNlbiB2ZWdkaXN0LCBpbmNsdWRlPUZBTFNFfQ0Kc29yZW5zZW4wMjwtdmVnZGlzdChBbGxEYXRhTm9TaW5nWmVybywgbWV0aG9kPSJicmF5IiwgYmluYXJ5PVRSVUUsIGRpYWc9VFJVRSwgdXBwZXI9RkFMU0UsIG5hLnJtID0gRkFMU0UpDQoNCnNvcmVuc2VuLm5tZHMwMiA8LSBtZXRhTURTKHNvcmVuc2VuMDIsIGs9MTApDQpzb3JzdHJlc3NwbG90MDI8LXN0cmVzc3Bsb3Qoc29yZW5zZW4ubm1kczAyKQ0KYmVlcChzb3VuZCA9IDEsIGV4cHIgPSBOVUxMKQ0KYGBgDQoNCmBgYHtyIEZvciB0aGUgUGVyTUFOT1ZBfQ0Kc3Vtc3Vtc1Blcm08LWNiaW5kKHN1bXN1bXMyLCBzaXRlc2l6ZXMkUGVybWFuZW5jZSkNCmNvbG5hbWVzKHN1bXN1bXNQZXJtKVtjb2xuYW1lcyhzdW1zdW1zUGVybSk9PSJzaXRlc2l6ZXMkUGVybWFuZW5jZSJdIDwtICJQZXJtYW5lbmNlIg0KYGBgDQoNCmBgYHtyfQ0KQWxsUlN1bXM8LWFzLmRhdGEuZnJhbWUocm93U3VtcyhBbGxQb25kc05vU2l0ZSkpDQpuYW1lcyhBbGxSU3Vtcyk8LWMoIlN1bSIpDQpzcHB4c2l0ZXMuVDwtc2VsZWN0KHNwcHhzaXRlcywgYygxLCAxMiwgMTUsIDE2KSkNCm5hbWVzKHNwcHhzaXRlcy5UKTwtYygiU2l0ZSIsICJJRCIsICJEZXB0aCIsICJDYW5vcHkiKQ0KQWxsU2ltcDwtYWdncmVnYXRlKHNwcHhzaXRlcy5UWzM6NF0sIHNwcHhzaXRlcy5UWzE6Ml0sIGNvbXByZXNzKQ0KcXVhZHZhcnNzdW1zPC1jYmluZChBbGxTaW1wLCBBbGxSU3VtcykNCmBgYA0KDQpgYGB7cn0NCnN1bXN1bXNzaXRlPC1jYmluZChzdW1zdW1zMywgc2l0ZXNpemVzJFNpdGUpDQpjb2xuYW1lcyhzdW1zdW1zc2l0ZSlbY29sbmFtZXMoc3Vtc3Vtc3NpdGUpPT0ic2l0ZXNpemVzJFNpdGUiXSA8LSAiU2l0ZSINCnN1bXNpdGVyYXVwPC1zdWJzZXQoc3Vtc3Vtc3NpdGUsIHNlbGVjdD1jKDMxMywxOjMxMikpDQpgYGANCg0KYGBge3J9DQpyYXVwX2NyaWNrPWZ1bmN0aW9uKHNwWHNpdGUsIHBsb3RfbmFtZXNfaW5fY29sMT1UUlVFLCBjbGFzc2ljX21ldHJpYz1GQUxTRSwgc3BsaXRfdGllcz1UUlVFLCByZXBzPTk5OTksIHNldF9hbGxfc3BlY2llc19lcXVhbD1GQUxTRSwgYXMuZGlzdGFuY2UubWF0cml4PVRSVUUsIHJlcG9ydF9zaW1pbGFyaXR5PUZBTFNFKXsNCgkjI2V4cGVjdHMgYSBzcGVjaWVzIGJ5IHNpdGUgbWF0cml4IGZvciBzcFhzaXRlLCB3aXRoIHJvdyBuYW1lcyBmb3IgcGxvdHMsIG9yIG9wdGlvbmFsbHkgcGxvdHMgbmFtZWQgaW4gY29sdW1uIDEuICBCeSBkZWZhdWx0IGNhbGN1bGF0ZXMgYSBtb2RpZmljYXRpb24gb2YgdGhlIFJhdXAtQ3JpY2sgbWV0cmljIChzdGFuZGFyZGl6aW5nIHRoZSBtZXRyaWMgdG8gcmFuZ2UgZnJvbSAtMSB0byAxIGluc3RlYWQgb2YgMCB0byAxKS4gU3BlY2lmeWluZyBjbGFzc2ljX21ldHJpYz1UUlVFIGluc3RlYWQgY2FsY3VsYXRlcyB0aGUgb3JpZ2luYWwgUmF1cC1DcmljayBtZXRyaWMgdGhhdCByYW5nZXMgZnJvbSAwIHRvIDEuIFRoZSBvcHRpb24gc3BsaXRfdGllcyAoZGVmYXVsdHMgdG8gVFJVRSkgYWRkcyBoYWxmIG9mIHRoZSBudW1iZXIgb2YgbnVsbCBvYnNlcnZhdGlvbnMgdGhhdCBhcmUgZXF1YWwgdG8gdGhlIG9ic2VydmVkIG51bWJlciBvZiBzaGFyZWQgc3BlY2llcyB0byB0aGUgY2FsY3VsYXRpb24tIHRoaXMgaXMgaGlnaGx5IHJlY29tbWVuZGVkLiAgVGhlIGFyZ3VtZW50IHJlcG9ydF9zaW1pbGFyaXR5IGRlZmF1bHRzIHRvIEZBTFNFIHNvIHRoZSBmdW5jdGlvbiByZXBvcnRzIGEgZGlzc2ltaWxhcml0eSAod2hpY2ggaXMgYXBwcm9wcmlhdGUgYXMgYSBtZWFzdXJlIG9mIGJldGEgZGl2ZXJzaXR5KS4gIFNldHRpbmcgcmVwb3J0X3NpbWlsYXJpdHk9VFJVRSByZXR1cm5zIGEgbWVhc3VyZSBvZiBzaW1pbGFyaXR5LCBhcyBSYXVwIGFuZCBDcmljayBvcmlnaW5hbGx5IHNwZWNpZmllZC4gIElmIHRpZXMgYXJlIHNwbGl0IChhcyB3ZSByZWNvbW1lbmQpIHRoZSBkaXNzaW1pbGFyaXR5IChkZWZhdWx0KSBhbmQgc2ltaWxhcml0eSAoc2V0IHJlcG9ydF9zaW1pbGFyaXR5PVRSVUUpIGNhbGN1bGF0aW9ucyBjYW4gYmUgZmxpcHBlZCBieSBtdWx0aXBseWluZyBieSAtMSAoZm9yIG91ciBtb2RpZmljYXRpb24sIHdoaWNoIHJhbmdlcyBmcm9tIC0xIHRvIDEpIG9yIGJ5IHN1YnRyYWN0aW5nIHRoZSBtZXRyaWMgZnJvbSAxIChmb3IgdGhlIGNsYXNzaWMgbWV0cmljIHdoaWNoIHJhbmdlcyBmcm9tIDAgdG8gMSkuIElmIHRpZXMgYXJlIG5vdCBzcGxpdCAoYW5kIHRoZXJlIGFyZSB0aWVzIGJldHdlZW4gdGhlIG9ic2VydmVkIGFuZCBleHBlY3RlZCBzaGFyZWQgbnVtYmVyIG9mIHNwZWNpZXMpIHRoaXMgY29udmVyc2lvbiB3aWxsIG5vdCB3b3JrLiBUaGUgYXJndW1lbnQgcmVwcyBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiByYW5kb21pemF0aW9ucyAoYSBtaW5pbXVtIG9mIDk5OSBpcyByZWNvbW1lbmRlZC0gZGVmYXVsdCBpcyA5OTk5KS4gIHNldF9hbGxfc3BlY2llc19lcXVhbCB3ZWlnaHRzIGFsbCBzcGVjaWVzIGVxdWFsbHkgaW4gdGhlIG51bGwgbW9kZWwgaW5zdGVhZCBvZiB3ZWlnaHRpbmcgc3BlY2llcyBieSBmcmVxdWVuY3kgb2Ygb2NjdXBhbmN5LiAgDQoJIyNOb3RlIHRoYXQgdGhlIGNob2ljZSBvZiBob3cgbWFueSBwbG90cyAocm93cykgdG8gaW5jbHVkZSBoYXMgYSByZWFsIGltcGFjdCBvbiB0aGUgbWV0cmljLCBhcyBzcGVjaWVzIGFuZCB0aGVpciBvY2N1cnJlbmNlIGZyZXF1ZW5jaWVzIGFjcm9zcyB0aGUgc2V0IG9mIHBsb3RzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGdhbW1hIGFuZCB0aGUgZnJlcXVlbmN5IHdpdGggd2hpY2ggZWFjaCBzcGVjaWVzIGlzIGRyYXduIGZyb20gdGhlIG51bGwgbW9kZWwJDQoJIyN0aGlzIHNlY3Rpb24gbW92ZXMgcGxvdCBuYW1lcyBpbiBjb2x1bW4gMSAoaWYgc3BlY2lmaWVkIGFzIGJlaW5nIHByZXNlbnQpIGludG8gdGhlIHJvdyBuYW1lcyBvZiB0aGUgbWF0cml4IGFuZCBkcm9wcyB0aGUgY29sdW1uIG9mIG5hbWVzDQoJaWYocGxvdF9uYW1lc19pbl9jb2wxKXsNCgkJcm93Lm5hbWVzKHNwWHNpdGUpPC1zcFhzaXRlWywxXQ0KCQlzcFhzaXRlPC1zcFhzaXRlWywtMV0NCgkJfQ0KCSMjIGNvdW50IG51bWJlciBvZiBzaXRlcyBhbmQgdG90YWwgc3BlY2llcyByaWNobmVzcyBhY3Jvc3MgYWxsIHBsb3RzIChnYW1tYSkNCgluX3NpdGVzPC1ucm93KHNwWHNpdGUpDQoJZ2FtbWE8LW5jb2woc3BYc2l0ZSkNCgkjI21ha2UgdGhlIHNwWHNpdGUgbWF0cml4IGludG8gYSBwcmVzL2Ficy4gKG92ZXJ3cml0ZXMgaW5pdGlhbCBzcFhzaXRlIG1hdHJpeCk6DQoJY2VpbGluZyhzcFhzaXRlL21heChzcFhzaXRlKSktPnNwWHNpdGUNCgkjI2NyZWF0ZSBhbiBvY2N1cnJlbmNlIHZlY3Rvci0gdXNlZCB0byBnaXZlIG1vcmUgd2VpZ2h0IHRvIHdpZGVseSBkaXN0cmlidXRlZCBzcGVjaWVzIGluIHRoZSBudWxsIG1vZGVsOg0KCW9jY3VyPC1hcHBseShzcFhzaXRlLCBNQVJHSU49MiwgRlVOPXN1bSkNCgkjI05PVCByZWNvbW1lbmRlZC0gdGhpcyBpcyBhIG5vbi10cml2aWFsIGNoYW5nZSB0byB0aGUgbWV0cmljOg0KCSMjc2V0cyBhbGwgc3BlY2llcyB0byBvY2N1ciB3aXRoIGVxdWFsIGZyZXF1ZW5jeSBpbiB0aGUgbnVsbCBtb2RlbA0KCSMjZS5nLi0gZGlzY2FyZHMgYW55IG9jY3VwYW5jeSBmcmVxdWVuY3kgaW5mb3JtYXRpb24NCglpZihzZXRfYWxsX3NwZWNpZXNfZXF1YWwpew0KCQlvY2N1cjwtcmVwKDEsZ2FtbWEpDQoJCX0NCgkjIyBkZXRlcm1pbmUgaG93IG1hbnkgdW5pcXVlIHNwZWNpZXMgcmljaG5lc3MgdmFsdWVzIGFyZSBpbiB0aGUgZGF0YXNldA0KCSMjdGhpcyBpcyB1c2VkIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgbnVsbCBjb21tdW5pdGllcyB0aGF0IGhhdmUgdG8gYmUgY2FsY3VsYXRlZA0KCWFscGhhX2xldmVsczwtc29ydCh1bmlxdWUoYXBwbHkoc3BYc2l0ZSwgTUFSR0lOPTEsIEZVTj1zdW0pKSkNCgkjI21ha2VfbnVsbDoNCgkjI2FscGhhX3RhYmxlIGlzIHVzZWQgYXMgYSBsb29rdXAgdG8gaGVscCBpZGVudGlmeSB3aGljaCBudWxsIGRpc3RyaWJ1dGlvbiB0byB1c2UgZm9yIHRoZSB0ZXN0cyBsYXRlci4gIEl0IGNvbnRhaW5zIG9uZSByb3cgZm9yIGVhY2ggY29tYmluYXRpb24gb2YgYWxwaGEgcmljaG5lc3MgbGV2ZWxzLiANCglhbHBoYV90YWJsZTwtZGF0YS5mcmFtZShjKE5BKSwgYyhOQSkpDQoJbmFtZXMoYWxwaGFfdGFibGUpPC1jKCJzbWFsbGVyX2FscGhhIiwgImJpZ2dlcl9hbHBoYSIpDQoJY29sX2NvdW50PC0xDQoJIyNudWxsX2FycmF5IHdpbGwgaG9sZCB0aGUgYWN0dWFsIG51bGwgZGlzdHJpYnV0aW9uIHZhbHVlcy4gIEVhY2ggZWxlbWVudCBvZiB0aGUgYXJyYXkgY29ycmVzcG9uZHMgdG8gYSBudWxsIGRpc3RyaWJ1dGlvbiBmb3IgZWFjaCBjb21iaW5hdGlvbiBvZiBhbHBoYSB2YWx1ZXMuICBUaGUgYWxwaGFfdGFibGUgaXMgdXNlZCB0byBwb2ludCB0byB0aGUgY29ycmVjdCBudWxsIGRpc3RyaWJ1dGlvbi0gdGhlIHJvdyBudW1iZXJzIG9mIGFscGhhX3RhYmxlIGNvcnJlc3BvbmQgdG8gdGhlIFtbeF1dIGluZGljZXMgb2YgdGhlIG51bGxfYXJyYXkuICBMYXRlciB0aGUgZnVuY3Rpb24gd2lsbCBmaW5kIHRoZSByb3cgb2YgYWxwaGFfdGFibGUgd2l0aCB0aGUgcmlnaHQgY29tYmluYXRpb24gb2YgYWxwaGEgdmFsdWVzLiAgVGhhdCByb3cgbnVtYmVyIGlzIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGVsZW1lbnQgb2YgbnVsbF9hcnJheSB0aGF0IGNvbnRhaW5zIHRoZSBjb3JyZWN0IG51bGwgZGlzdHJpYnV0aW9uIGZvciB0aGF0IGNvbWJpbmF0aW9uIG9mIGFscGhhIGxldmVscy4gDQoJbnVsbF9hcnJheTwtbGlzdCgpDQoJIyNsb29waW5nIG92ZXIgZWFjaCBjb21iaW5hdGlvbiBvZiBhbHBoYSBsZXZlbHM6DQoJZm9yKGExIGluIDE6bGVuZ3RoKGFscGhhX2xldmVscykpew0KCQlmb3IoYTIgaW4gYTE6bGVuZ3RoKGFscGhhX2xldmVscykpew0KCQkJIyNidWlsZCBhIG51bGwgZGlzdHJpYnV0aW9uIG9mIHRoZSBudW1iZXIgb2Ygc2hhcmVkIHNwZWNpZXMgZm9yIGEgcGFpciBvZiBhbHBoYSB2YWx1ZXM6DQoJCQludWxsX3NoYXJlZF9zcHA8LU5VTEwNCgkJCWZvcihpIGluIDE6cmVwcyl7DQoJCQkJIyN0d28gZW1wdHkgbnVsbCBjb21tdW5pdGllcyBvZiBzaXplIGdhbW1hOg0KCQkJCWNvbTE8LXJlcCgwLGdhbW1hKQ0KCQkJCWNvbTI8LXJlcCgwLGdhbW1hKQ0KCQkJCSMjYWRkIGFscGhhMSBudW1iZXIgb2Ygc3BlY2llcyB0byBjb20xLCB3ZWlnaHRpbmcgYnkgc3BlY2llcyBvY2N1cnJlbmNlIGZyZXF1ZW5jaWVzOg0KCQkJCWNvbTFbc2FtcGxlKDE6Z2FtbWEsIGFscGhhX2xldmVsc1thMV0sIHJlcGxhY2U9RkFMU0UsIHByb2I9b2NjdXIpXTwtMQ0KCQkJCSMjc2FtZSBmb3IgY29tMjoNCgkJCQljb20yW3NhbXBsZSgxOmdhbW1hLCBhbHBoYV9sZXZlbHNbYTJdLCByZXBsYWNlPUZBTFNFLCBwcm9iPW9jY3VyKV08LTENCgkJCQkjI2hvdyBtYW55IHNwZWNpZXMgYXJlIHNoYXJlZCBpbiBjb21tb24/DQoJCQkJbnVsbF9zaGFyZWRfc3BwW2ldPC1zdW0oKGNvbTErY29tMik+MSkNCgkJCQl9DQoJCQkjI3N0b3JlIG51bGwgZGlzdHJpYnV0aW9uLCByZWNvcmQgdmFsdWVzIGZvciBhbHBoYSAxIGFuZCAyIGluIHRoZSBhbHBoYV90YWJsZSB0byBoZWxwIGZpbmQgdGhlIGNvcnJlY3QgbnVsbCBkaXN0cmlidXRpb24gbGF0ZXI6DQoJCQludWxsX2FycmF5W1tjb2xfY291bnRdXTwtbnVsbF9zaGFyZWRfc3BwDQoJCQlhbHBoYV90YWJsZVtjb2xfY291bnQsIHdoaWNoKG5hbWVzKGFscGhhX3RhYmxlKT09InNtYWxsZXJfYWxwaGEiKV08LWFscGhhX2xldmVsc1thMV0NCgkJCWFscGhhX3RhYmxlW2NvbF9jb3VudCwgd2hpY2gobmFtZXMoYWxwaGFfdGFibGUpPT0iYmlnZ2VyX2FscGhhIildPC1hbHBoYV9sZXZlbHNbYTJdDQoJCQkjaW5jcmVtZW50IHRoZSBjb3VudGVyIGZvciB0aGUgY29sdW1ucyBvZiB0aGUgYWxwaGEgdGFibGUvIGVsZW1lbnRzIG9mIHRoZSBudWxsIGFycmF5DQoJCQljb2xfY291bnQ8LWNvbF9jb3VudCsxDQoJCQl9DQoJCX0NCgkjI2NyZWF0ZSBhIG5ldyBjb2x1bW4gd2l0aCBib3RoIGFscGhhIGxldmVscyB0byBtYXRjaCBvbjoNCglhbHBoYV90YWJsZSRtYXRjaGluZzwtcGFzdGUoYWxwaGFfdGFibGVbLDFdLCBhbHBoYV90YWJsZVssMl0sIHNlcD0iXyIpDQoJDQoJIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoJIyNkbyB0aGUgdGVzdDoNCgkjI2J1aWxkIGEgc2l0ZSBieSBzaXRlIG1hdHJpeCBmb3IgdGhlIHJlc3VsdHMsIHdpdGggdGhlIG5hbWVzIG9mIHRoZSBzaXRlcyBpbiB0aGUgcm93IGFuZCBjb2wgbmFtZXM6DQoJcmVzdWx0czwtbWF0cml4KGRhdGE9TkEsIG5yb3c9bl9zaXRlcywgbmNvbD1uX3NpdGVzLCBkaW1uYW1lcz1saXN0KHJvdy5uYW1lcyhzcFhzaXRlKSwgcm93Lm5hbWVzKHNwWHNpdGUpKSkNCgkjI2ZvciBlYWNoIHBhaXIgb2Ygc2l0ZXMgKGR1cGxpY2F0ZXMgZWZmb3J0IG5vdyB0byBtYWtlIGEgZnVsbCBtYXRyaXggaW5zdGVhZCBvZiBhIGhhbGYgb25lLSBidXQgdGhpcyBwYXJ0IHNob3VsZCBiZSBtaW5pbWFsIHRpbWUgYXMgY29tcGFyZWQgdG8gdGhlIG51bGwgbW9kZWwgYnVpbGRpbmcpDQoJZm9yKGkgaW4gMTpuX3NpdGVzKXsNCgkJZm9yKGogaW4gMTpuX3NpdGVzKXsNCgkJCSMjaG93IG1hbnkgc3BlY2llcyBhcmUgc2hhcmVkIGJldHdlZW4gdGhlIHR3byBzaXRlczoNCgkJCW5fc2hhcmVkX29iczwtc3VtKChzcFhzaXRlW2ksXStzcFhzaXRlW2osXSk+MSkNCgkJCSMjIHdoYXQgd2FzIHRoZSBvYnNlcnZlZCByaWNobmVzcyBvZiBlYWNoIHNpdGU/DQoJCQlvYnNfYTE8LXN1bShzcFhzaXRlW2ksXSkNCgkJCW9ic19hMjwtc3VtKHNwWHNpdGVbaixdKQ0KCQkJIyNwbGFjZSB0aGVzZSBhbHBoYXMgaW50byBhbiBvYmplY3QgdG8gbWF0Y2ggYWdhaW5zdCBhbHBoYV90YWJsZSAoc29ydCBzbyBzbWFsbGVyIGFscGhhIGlzIGZpcnN0KQ0KCQkJb2JzX2FfcGFpcjwtc29ydChjKG9ic19hMSwgb2JzX2EyKSkNCgkJCSMjbWF0Y2ggYWdhaW5zdCB0aGUgYWxwaGEgdGFibGUtIHJvdyBpbmRleCBpZGVudGlmaWVzIHdoaWNoIGVsZW1lbnQgb2YgdGhlIG51bGwgYXJyYXkgY29udGFpbnMgdGhlIGNvcnJlY3QgbnVsbCBkaXN0cmlidXRpb24gZm9yIHRoZSBvYnNlcnZlZCBjb21iaW5hdGlvbiBvZiBhbHBoYSB2YWx1ZXM6DQoJCQludWxsX2luZGV4PC13aGljaChhbHBoYV90YWJsZSRtYXRjaGluZz09cGFzdGUob2JzX2FfcGFpclsxXSwgb2JzX2FfcGFpclsyXSwgc2VwPSJfIikpDQoJCQkjI2hvdyBtYW55IG51bGwgb2JzZXJ2YXRpb25zIGlzIHRoZSBvYnNlcnZlZCB2YWx1ZSB0aWVkIHdpdGg/DQoJCQludW1fZXhhY3RfbWF0Y2hpbmdfaW5fbnVsbDwtc3VtKG51bGxfYXJyYXlbW251bGxfaW5kZXhdXT09bl9zaGFyZWRfb2JzKQ0KCQkJIyNob3cgbWFueSBudWxsIHZhbHVlcyBhcmUgYmlnZ2VyIHRoYW4gdGhlIG9ic2VydmVkIHZhbHVlPw0KCQkJbnVtX2dyZWF0ZXJfaW5fbnVsbDwtc3VtKG51bGxfYXJyYXlbW251bGxfaW5kZXhdXT5uX3NoYXJlZF9vYnMpDQoJCQlyYzwtKG51bV9ncmVhdGVyX2luX251bGwpL3JlcHMNCgkJCWlmKHNwbGl0X3RpZXMpew0KCQkJCXJjPC0oKG51bV9ncmVhdGVyX2luX251bGwrKG51bV9leGFjdF9tYXRjaGluZ19pbl9udWxsKS8yKS9yZXBzKQ0KCQkJfQ0KCQkJaWYoIWNsYXNzaWNfbWV0cmljKXsJDQoJCQkJCSMjb3VyIG1vZGlmaWNhdGlvbiBvZiByYXVwIGNyaWNrIHN0YW5kYXJkaXplcyB0aGUgbWV0cmljIHRvIHJhbmdlIGZyb20gLTEgdG8gMSBpbnN0ZWFkIG9mIDAgdG8gMQ0KCQkJCQlyYzwtKHJjLS41KSoyDQoJCQl9DQoJCQkjIyBhdCB0aGlzIHBvaW50IHJjIHJlcHJlc2VudHMgYW4gaW5kZXggb2YgZGlzc2ltaWxhcml0eS0gbXVsdGlwbHkgYnkgLTEgdG8gY29udmVydCB0byBhIHNpbWlsYXJpdHkgYXMgc3BlY2lmaWVkIGluIHRoZSBvcmlnaW5hbCAxOTc5IFJhdXAgQ3JpY2sgcGFwZXINCgkJCWlmKHJlcG9ydF9zaW1pbGFyaXR5ICYgIWNsYXNzaWNfbWV0cmljKXsNCgkJCQlyYzwtIHJjKi0xDQoJCQkJfQ0KCQkJIyMgdGhlIHN3aXRjaCB0byBzaW1pbGFyaXR5IGlzIGRvbmUgZGlmZmVyZW50bHkgaWYgdGhlIG9yaWdpbmFsIDAgdG8gMSByYW5nZSBvZiB0aGUgbWV0cmljIGlzIHVzZWQ6DQoJCQlpZihyZXBvcnRfc2ltaWxhcml0eSAmIGNsYXNzaWNfbWV0cmljKXsNCgkJCQlyYzwtIDEtcmMNCgkJCQl9DQoJCQkjI3N0b3JlIHRoZSBtZXRyaWMgaW4gdGhlIHJlc3VsdHMgbWF0cml4Og0KCQkJcmVzdWx0c1tpLGpdPC1yb3VuZChyYywgZGlnaXRzPTIpDQoJCQl9DQoJCX0NCmlmKGFzLmRpc3RhbmNlLm1hdHJpeCl7DQoJcmVzdWx0czwtYXMuZGlzdChyZXN1bHRzKQ0KCX0JDQpyZXR1cm4ocmVzdWx0cykNCgl9DQpgYGANCg0KYGBge3J9DQpyYXVweTwtcmF1cF9jcmljayhzdW1zaXRlcmF1cCwgcGxvdF9uYW1lc19pbl9jb2wxPVRSVUUsIGNsYXNzaWNfbWV0cmljPUZBTFNFLCBzcGxpdF90aWVzPVRSVUUsIHJlcHM9OTk5OSwgc2V0X2FsbF9zcGVjaWVzX2VxdWFsPUZBTFNFLCBhcy5kaXN0YW5jZS5tYXRyaXg9VFJVRSwgcmVwb3J0X3NpbWlsYXJpdHk9RkFMU0UpDQpiZWVwKHNvdW5kID0gMSwgZXhwciA9IE5VTEwpDQpgYGANCg0KDQoNCg0KIyMgQmFja2dyb3VuZCANCg0KPGZpZ3VyZT4NCjxpbWcgc3JjPSJJbWFnZXMvUXVhZHJhdENyb3BwZWQuanBnIj48L2ZpZ3VyZT48YnI+DQoNCiMjIyBEYXRhIENvbGxlY3Rpb24NCg0KUGxvdHMgd2VyZSBzYW1wbGVkIGF0IDI3IGluZGVwZW5kZW50IHNpdGVzIHRocm91Z2hvdXQgYSBzdWJzZXQgb2YgdGhlIEVhc3Rlcm4gSGlnaGxhbmQgUmltIGVjb3JlZ2lvbiAoZGVsaW5lYXRlZCBpbiB0YW4gYmVsb3cpLiBOb3RlIHRoYXQgc29tZSBzaXRlcyB3ZXJlIGFsc28gaW4gY2xvc2UgcHJveGltaXR5LCBtYWtpbmcgdGhlbSBkaWZmaWN1bHQgdG8gc2VlIA0KDQpgYGB7ciBMZWFmbGV0IG1hcCwgZWNobz1GQUxTRSwgZmlnLndpZHRoID0gOC41LCBmaWcuaGVpZ2h0ID0gNS41fQ0KIyBsZWFmbGV0KGRhdGE9c2l0ZXNpemVzKSU+JQ0KIyAgIHNldFZpZXcoLTg1Ljg3MjM3LCAzNS43ODE2NSwgem9vbT03KSU+JSANCiMgICBhZGRUaWxlcygpJT4lDQojICAgICAgIGFkZFBvbHlnb25zKG91dGxpbmVfcG9seWEsIA0KIyAgICAgICAgICAgICAgIGxuZyA9IG91dGxpbmVfcG9seWFAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMV0sIA0KIyAgICAgICAgICAgICAgIGxhdCA9IG91dGxpbmVfcG9seWFAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMl0sDQojICAgICAgICAgICAgICAgY29sb3IgPSAiI0REOEQyOSIsDQojICAgICAgICAgICAgICAgb3BhY2l0eT0gOSwNCiMgICAgICAgICAgICAgICB3ZWlnaHQgPSAyKSAlPiUNCiMgICAgICAgYWRkUG9seWdvbnMob3V0bGluZV9wb2x5YiwgDQojICAgICAgICAgICAgICAgbG5nID0gb3V0bGluZV9wb2x5YkBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywxXSwgDQojICAgICAgICAgICAgICAgbGF0ID0gb3V0bGluZV9wb2x5YkBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSwNCiMgICAgICAgICAgICAgICBjb2xvciA9ICIjREQ4RDI5IiwNCiMgICAgICAgICAgICAgICBvcGFjaXR5PSA5LA0KIyAgICAgICAgICAgICAgIHdlaWdodCA9IDIpICU+JQ0KIyAgICAgICBhZGRQb2x5Z29ucyhvdXRsaW5lX3BvbHljLCANCiMgICAgICAgICAgICAgICBsbmcgPSBvdXRsaW5lX3BvbHljQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLCANCiMgICAgICAgICAgICAgICBsYXQgPSBvdXRsaW5lX3BvbHljQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDJdLA0KIyAgICAgICAgICAgICAgIGNvbG9yID0gIiNERDhEMjkiLA0KIyAgICAgICAgICAgICAgIG9wYWNpdHk9IDksDQojICAgICAgICAgICAgICAgd2VpZ2h0ID0gMikgJT4lDQojICAgICAgIGFkZFBvbHlnb25zKG91dGxpbmVfcG9seWQsIA0KIyAgICAgICAgICAgICAgIGxuZyA9IG91dGxpbmVfcG9seWRAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMV0sIA0KIyAgICAgICAgICAgICAgIGxhdCA9IG91dGxpbmVfcG9seWRAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMl0sDQojICAgICAgICAgICAgICAgY29sb3IgPSAiI0REOEQyOSIsDQojICAgICAgICAgICAgICAgb3BhY2l0eT0gOSwNCiMgICAgICAgICAgICAgICB3ZWlnaHQgPSAyKSAlPiUNCiMgICAgICAgYWRkUG9seWdvbnMob3V0bGluZV9wb2x5ZSwgDQojICAgICAgICAgICAgICAgbG5nID0gb3V0bGluZV9wb2x5ZUBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywxXSwgDQojICAgICAgICAgICAgICAgbGF0ID0gb3V0bGluZV9wb2x5ZUBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSwNCiMgICAgICAgICAgICAgICBjb2xvciA9ICIjREQ4RDI5IiwNCiMgICAgICAgICAgICAgICBvcGFjaXR5PSA5LA0KIyAgICAgICAgICAgICAgIHdlaWdodCA9IDIpICU+JQ0KIyAgICAgICBhZGRQb2x5Z29ucyhvdXRsaW5lX3BvbHlmLCANCiMgICAgICAgICAgICAgICBsbmcgPSBvdXRsaW5lX3BvbHlmQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLCANCiMgICAgICAgICAgICAgICBsYXQgPSBvdXRsaW5lX3BvbHlmQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDJdLA0KIyAgICAgICAgICAgICAgIGNvbG9yID0gIiNERDhEMjkiLA0KIyAgICAgICAgICAgICAgIG9wYWNpdHk9IDksDQojICAgICAgICAgICAgICAgd2VpZ2h0ID0gMikgJT4lDQojICAgICAgIGFkZFBvbHlnb25zKG91dGxpbmVfcG9seWcsIA0KIyAgICAgICAgICAgICAgIGxuZyA9IG91dGxpbmVfcG9seWdAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMV0sIA0KIyAgICAgICAgICAgICAgIGxhdCA9IG91dGxpbmVfcG9seWdAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMl0sDQojICAgICAgICAgICAgICAgY29sb3IgPSAiI0REOEQyOSIsDQojICAgICAgICAgICAgICAgb3BhY2l0eT0gOSwNCiMgICAgICAgICAgICAgICB3ZWlnaHQgPSAyKSAlPiUNCiMgICAgICAgYWRkUG9seWdvbnMob3V0bGluZV9wb2x5aCwgDQojICAgICAgICAgICAgICAgbG5nID0gb3V0bGluZV9wb2x5aEBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywxXSwgDQojICAgICAgICAgICAgICAgbGF0ID0gb3V0bGluZV9wb2x5aEBwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSwNCiMgICAgICAgICAgICAgICBjb2xvciA9ICIjREQ4RDI5IiwNCiMgICAgICAgICAgICAgICBvcGFjaXR5PSA5LA0KIyAgICAgICAgICAgICAgIHdlaWdodCA9IDIpICU+JQ0KIyAgICAgICBhZGRQb2x5Z29ucyhvdXRsaW5lX3BvbHlpLCANCiMgICAgICAgICAgICAgICBsbmcgPSBvdXRsaW5lX3BvbHlpQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLCANCiMgICAgICAgICAgICAgICBsYXQgPSBvdXRsaW5lX3BvbHlpQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDJdLA0KIyAgICAgICAgICAgICAgIGNvbG9yID0gIiNERDhEMjkiLA0KIyAgICAgICAgICAgICAgIG9wYWNpdHk9IDksDQojICAgICAgICAgICAgICAgd2VpZ2h0ID0gMikgJT4lDQojICAgICAgIGFkZFBvbHlnb25zKG91dGxpbmVfcG9seWosIA0KIyAgICAgICAgICAgICAgIGxuZyA9IG91dGxpbmVfcG9seWpAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMV0sIA0KIyAgICAgICAgICAgICAgIGxhdCA9IG91dGxpbmVfcG9seWpAcG9seWdvbnNbWzFdXUBQb2x5Z29uc1tbMV1dQGNvb3Jkc1ssMl0sDQojICAgICAgICAgICAgICAgY29sb3IgPSAiI0REOEQyOSIsDQojICAgICAgICAgICAgICAgb3BhY2l0eT0gOSwNCiMgICAgICAgICAgICAgICB3ZWlnaHQgPSAyKSAlPiUNCiMgICAgICAgYWRkUG9seWdvbnMob3V0bGluZV9wb2x5aywgDQojICAgICAgICAgICAgICAgbG5nID0gb3V0bGluZV9wb2x5a0Bwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywxXSwgDQojICAgICAgICAgICAgICAgbGF0ID0gb3V0bGluZV9wb2x5a0Bwb2x5Z29uc1tbMV1dQFBvbHlnb25zW1sxXV1AY29vcmRzWywyXSwNCiMgICAgICAgICAgICAgICBjb2xvciA9ICIjREQ4RDI5IiwNCiMgICAgICAgICAgICAgICBvcGFjaXR5PSA5LA0KIyAgICAgICAgICAgICAgIHdlaWdodCA9IDIpICU+JQ0KIyAgICAgICBhZGRQb2x5Z29ucyhvdXRsaW5lX3BvbHlsLCANCiMgICAgICAgICAgICAgICBsbmcgPSBvdXRsaW5lX3BvbHlsQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDFdLCANCiMgICAgICAgICAgICAgICBsYXQgPSBvdXRsaW5lX3BvbHlsQHBvbHlnb25zW1sxXV1AUG9seWdvbnNbWzFdXUBjb29yZHNbLDJdLA0KIyAgICAgICAgICAgICAgIGNvbG9yID0gIiNERDhEMjkiLA0KIyAgICAgICAgICAgICAgIG9wYWNpdHk9IDksDQojICAgICAgICAgICAgICAgd2VpZ2h0ID0gMikgJT4lDQojICAgICAgIGFkZENpcmNsZU1hcmtlcnMoZGF0YSA9IHNpdGVzaXplcywgbGF0ID0gfkxhdGl0dWRlLCBsbmcgPSB+TG9uZ2l0dWRlLA0KIyAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSB+U2l0ZSwNCiMgICAgICAgICAgICAgICAgICAgIHBvcHVwID0gfkNvbW11bml0eSwNCiMgICAgICAgICAgICAgICAgICAgIG9wYWNpdHk9IDEwMCwNCiMgICAgICAgICAgICAgICAgICAgIHdlaWdodCA9IDIsDQojICAgICAgICAgICAgICAgICAgICBjb2xvcj0gImJsYWNrIiwNCiMgICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9IH40KSU+JQ0KIyAgIGFkZFByb3ZpZGVyVGlsZXMocHJvdmlkZXJzJEVzcmkuTmF0R2VvV29ybGRNYXAsIGdyb3VwID0gIk5hdEdlbyIpJT4lDQojICAgYWRkUHJvdmlkZXJUaWxlcyhwcm92aWRlcnMkRXNyaS5Xb3JsZEltYWdlcnksIGdyb3VwID0gIkVTUkkiKSAlPiUNCiMgICBhZGRNaW5pTWFwKHpvb21MZXZlbE9mZnNldCA9IC00KSU+JQ0KIyAgIGFkZFNjYWxlQmFyKCklPiUNCiMgICBhZGRMYXllcnNDb250cm9sKA0KIyAgICAgYmFzZUdyb3VwcyA9IGMoIk5hdEdlbyIsICJFU1JJIiksDQojICAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpKQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KMTAzMSAxbV4yIHF1YWRyYXRzIHdlcmUgc2FtcGxlZCB3aXRoIGRpZmZlcmVpbmcgc2FtcGxlIHNpemVzIHBlciBzaXRlIGJhc2VkIG9uIHRoZSBzaXplIG9mIHRoZSBzaXRlLiANCg0KIyMjIERhdGEgQ29uZmlndXJhdGlvbg0KDQpOZWFybHkgYWxsIHN0YXRpc3RpY2FsIHBhY2thZ2VzIHJlcXVpcmUgdGhlIGRhdGEgdG8gYmUgaW4gYSBwcmVzZW5jZS1hYnNlbmNlIGZvcm0uIFRoZXJlIGFyZSBzZXZlcmFsIHdheXMgdG8gZG8gaXQgKG9uZSBvZiB3aGljaCBjYW4gbWFpbnRhaW4gY292ZXIgdmFsdWVzIHJhdGhlciB0aGFuIGNoYW5naW5nIGl0IHRvIGJpbmFyeSBkYXRhKTsgSSB1c2VkIGEgbG9vcCBmdW5jdGlvbi4gVGhlIHJlc3VsdCBpcyBhIHByZXNlbmNlLWFic2VuY2UgbWF0cml4IHdpdGggU2l0ZSBhcyBhIGNvbHVtbiBzbyBzdWJzYW1wbGVzIGNhbiBiZSBvcmdhbml6ZWQgYWNjb3JkaW5nbHkuIA0KDQoNCg0KYGBge3IgS2FibGUgMSwgZWNobz1GQUxTRX0NCkFsbFBvbmRzVHJpbW1lZDwtc2VsZWN0KEFsbFBvbmRzLCBjKDE6NykpDQprYWJsZShBbGxQb25kc1RyaW1tZWRbMTo1LCBdLCBmb3JtYXQgPSAicGFuZG9jIiwgZnVsbF93aWR0aD1GLCBjYXB0aW9uID0gJ1RhYmxlIDEuIFNhbXBsZSBvZiBkYXRhIGluIHByZXNlbmNlLWFic2VuY2UgZm9ybWF0LicpDQpgYGANCg0KDQojIyBEaXZlcnNpdHkNCg0KDQoNCg0KYGBge3IgRXN0IGFuZCBPYnMgUmljaG5lc3MgUGxvdCwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIGpwZWcoZmlsZT0iUmljaG5lc3NTaXRlcy5qcGVnIikNCmdncGxvdChSaWNoR2F0aCwgYWVzKHg9U2l0ZSwgeT12YWx1ZSwgY29sb3I9UmljaG5lc3MpKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiZGFya2dyZXkiLCAiYmxhY2siKSkrDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49UmljaExDTCwgeW1heD1SaWNoVUNMKSwgd2lkdGg9LjMsIGNvbG9yPSJkYXJrZ3JleSIpICsNCiAgZ2VvbV9wb2ludChzaXplPTIpKw0KICB5bGFiKCJTcGVjaWVzIFJpY2huZXNzIikrDQogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLCAyNTApKSsNCiAgZ2d0aXRsZSgiRXN0aW1hdGVkIGFuZCBvYnNlcnZlZCBzcGVjaWVzIHJpY2huZXNzIGJ5IHNpdGUsIHdpdGggOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLiIpKw0KICBsYWJzKGNhcHRpb249IlVwcGVyIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIFNpdGUgMTAgZXh0ZW5kcyB0byAzMzAuODAuIikrDQogIHRoZW1lKGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTQpLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQ0KIyBkZXYub2ZmKCkNCmBgYA0KDQpTaXRlcyBoYWQgd2lkZWx5IHZhcnlpbmcgb2JzZXJ2ZWQgdG90YWwgcmljaG5lc3MuIFRoZSB1c2Ugb2YgZXh0cmFwb2xhdGVkIHNwZWNpZXMgYWNjdW11bGF0aW9uIGN1cnZlcyBjYW4gdGVsbCB1cyBob3cgbWFueSBzcGVjaWVzIGFyZSBsaWtlbHkgdG8gYmUgYXQgdGhlIHNpdGUgYmFzZWQgb24gaG93IG1hbnkgd2VyZSBmb3VuZCBpbiBhY2N1bXVsYXRpbmcgc3Vic2FtcGxlcy4gSG93ZXZlciBpZiBhIGN1cnZlIG5ldmVyIGZsYXR0ZW5zLCBpdCBnaXZlcyBhIHdpbGQgZXN0aW1hdGUgb2YgcmljaG5lc3MgKHNlZSBTaXRlIDEwKS4NCg0KV2hhdCBkbyB0aGUgY3VydmVzIHRoYXQgbWFkZSB0aGVzZSBlc3RpbWF0ZXMgbG9vayBsaWtlPyBMZXQncyB0YWtlIGEgbG9vayENCg0KYGBge3IgVW5pY29ybiB2b21pdCwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUV9DQpnZ2lORVhUKG91dC5pbmMuYWxsLCB0eXBlPTEsIGNvbG9yLnZhcj0ic2l0ZSIpICsgDQogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE4KSArDQogIHlsYWIoIlNwZWNpZXMgUmljaG5lc3MiKSArDQogIHhsYWIoIk51bWJlciBvZiBRdWFkcmF0cyIpICsNCiAgZ2d0aXRsZSgiSW50ZXJwb2xhdGVkIGFuZCBleHRyYXBvbGF0ZWQgcmljaG5lc3MiKSArDQogIGxhYnMoY2FwdGlvbj0iQj0xMDAwMC4iKQ0KYGBgDQoNClRoaXMgcGxvdCBpcyBub3QgcGFydGljdWxhcmx5IGhlbHBmdWwgb3RoZXIgdGhhbiB0byB2aXN1YWxpemUgdGhlIGdlbmVyYWwgc3BhbiBvZiBvYnNlcnZlZCBhbmQgZXhwZWN0ZWQgcmljaG5lc3NlcyBhbmQgc2FtcGxpbmcgZWZmb3J0cy4gRXhhbWluaW5nIHRoZSBjdXJ2ZXMgaW4gcG9ydGlvbnMgb2YgMy00IGlzIG5lY2Vzc2FyeSB0byANCg0KYGBge3IgTWFueSBjdXJ2ZXMgb3V0cHV0LCBmaWcuaGVpZ2h0PTI1LCBmaWcud2lkdGg9NywgaW5jbHVkZT1GQUxTRX0NCiNSaWNobmVzcyAocT0wKSwgU2hhbm5vbiBEaXYgKHE9MSksIFNpbXBzb24gRGl2IChxPTIpDQojVXNlIGdyZXk9VFJVRSB0byBtYWtlIGFsbCBsaW5lcyBibGFjaw0Kb3V0LmluYzE8LWlORVhUKHNpdGUubGlzdC5mcmVxLjEsIHE9MCwgZGF0YXR5cGU9ImluY2lkZW5jZV9mcmVxIiwgc2l6ZT1OVUxMLCBuYm9vdD0xMDApDQpBPC1nZ2lORVhUKG91dC5pbmMxLCB0eXBlPTEsIGNvbG9yLnZhcj0ic2l0ZSIpICsgDQogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE4KSArDQogIHlsYWIoIlNwZWNpZXMgUmljaG5lc3MiKSArDQogIHhsYWIoIk51bWJlciBvZiBRdWFkcmF0cyIpICsNCiAgbGFicyhjYXB0aW9uPSJCPTEwMC4iKQ0KDQpvdXQuaW5jMjwtaU5FWFQoc2l0ZS5saXN0LmZyZXEuMiwgcT0wLCBkYXRhdHlwZT0iaW5jaWRlbmNlX2ZyZXEiLCBzaXplPU5VTEwsIG5ib290PTEwMCkNCkI8LWdnaU5FWFQob3V0LmluYzIsIHR5cGU9MSwgY29sb3IudmFyPSJzaXRlIikgKyANCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsNCiAgeWxhYigiU3BlY2llcyBSaWNobmVzcyIpICsNCiAgeGxhYigiTnVtYmVyIG9mIFF1YWRyYXRzIikgKw0KICBsYWJzKGNhcHRpb249IkI9MTAwLiIpDQoNCm91dC5pbmMzPC1pTkVYVChzaXRlLmxpc3QuZnJlcS4zLCBxPTAsIGRhdGF0eXBlPSJpbmNpZGVuY2VfZnJlcSIsIHNpemU9TlVMTCwgbmJvb3Q9MTAwKQ0KQzwtZ2dpTkVYVChvdXQuaW5jMywgdHlwZT0xLCBjb2xvci52YXI9InNpdGUiKSArIA0KICB0aGVtZV9idyhiYXNlX3NpemUgPSAxOCkgKw0KICB5bGFiKCJTcGVjaWVzIFJpY2huZXNzIikgKw0KICB4bGFiKCJOdW1iZXIgb2YgUXVhZHJhdHMiKSArDQogIGxhYnMoY2FwdGlvbj0iQj0xMDAuIikNCg0Kb3V0LmluYzQ8LWlORVhUKHNpdGUubGlzdC5mcmVxLjQsIHE9MCwgZGF0YXR5cGU9ImluY2lkZW5jZV9mcmVxIiwgc2l6ZT1OVUxMLCBuYm9vdD0xMDApDQpEPC1nZ2lORVhUKG91dC5pbmM0LCB0eXBlPTEsIGNvbG9yLnZhcj0ic2l0ZSIpICsgDQogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE4KSArDQogIHlsYWIoIlNwZWNpZXMgUmljaG5lc3MiKSArDQogIHhsYWIoIk51bWJlciBvZiBRdWFkcmF0cyIpICsNCiAgbGFicyhjYXB0aW9uPSJCPTEwMC4iKQ0KDQpvdXQuaW5jNTwtaU5FWFQoc2l0ZS5saXN0LmZyZXEuNSwgcT0wLCBkYXRhdHlwZT0iaW5jaWRlbmNlX2ZyZXEiLCBzaXplPU5VTEwsIG5ib290PTEwMCkNCkU8LWdnaU5FWFQob3V0LmluYzUsIHR5cGU9MSwgY29sb3IudmFyPSJzaXRlIikgKyANCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsNCiAgeWxhYigiU3BlY2llcyBSaWNobmVzcyIpICsNCiAgeGxhYigiTnVtYmVyIG9mIFF1YWRyYXRzIikgKw0KICBsYWJzKGNhcHRpb249IkI9MTAwLiIpDQoNCm91dC5pbmM2PC1pTkVYVChzaXRlLmxpc3QuZnJlcS42LCBxPTAsIGRhdGF0eXBlPSJpbmNpZGVuY2VfZnJlcSIsIHNpemU9TlVMTCwgbmJvb3Q9MTAwKQ0KRjwtZ2dpTkVYVChvdXQuaW5jNiwgdHlwZT0xLCBjb2xvci52YXI9InNpdGUiKSArIA0KICB0aGVtZV9idyhiYXNlX3NpemUgPSAxOCkgKw0KICB5bGFiKCJTcGVjaWVzIFJpY2huZXNzIikgKw0KICB4bGFiKCJOdW1iZXIgb2YgUXVhZHJhdHMiKSArDQogIGxhYnMoY2FwdGlvbj0iQj0xMDAuIikNCg0Kb3V0LmluYzc8LWlORVhUKHNpdGUubGlzdC5mcmVxLjcsIHE9MCwgZGF0YXR5cGU9ImluY2lkZW5jZV9mcmVxIiwgc2l6ZT1OVUxMLCBuYm9vdD0xMDApDQpHPC1nZ2lORVhUKG91dC5pbmM3LCB0eXBlPTEsIGNvbG9yLnZhcj0ic2l0ZSIpICsgDQogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE4KSArDQogIHlsYWIoIlNwZWNpZXMgUmljaG5lc3MiKSArDQogIHhsYWIoIk51bWJlciBvZiBRdWFkcmF0cyIpICsNCiAgbGFicyhjYXB0aW9uPSJCPTEwMC4iKQ0KDQoNCmdnYXJyYW5nZShBLCBCLCBDLCBELCBFLCBGLCBHLCBucm93PTcpDQpgYGANCg0KDQpUaGVzZSBjdXJ2ZXMgaWxsdXN0cmF0ZSBub3Qgb25seSAqd2hlcmUqIHRoZSBmbGF0dGVuaW5nIHBvaW50IChleHBlY3RlZCByaWNobmVzcykgb2NjdXJzLCBidXQgYWxzbyAqaG93IHF1aWNrbHkqLiBFeGFtaW5pbmcgYSBjdXJ2ZSBjYW4gYWxsb3cgc29tZW9uZSB0byBlc3RpbWF0ZSBob3cgbWFueSBtb3JlIHNhbXBsZXMgd291bGQgYmUgbmVlZGVkIHRvIHJlYWNoIHRoYXQgcG9pbnQsIGhvd2V2ZXIgaWYgZG9pbmcgc28gc2FtcGxlcyBhIGxhcmdlciBhcmVhIHRoZW4gdGhlIGN1cnZlIG1heSBuZXZlciBmbGF0dGVuLiANCg0KTGV0J3Mgc2VlIGlmIHNhbXBsaW5nIGVmZm9ydCAoIyBxdWFkcmF0cy9hcmVhIHNhbXBsZWQpIGFmZmVjdGVkIHBlcmNlbnQgZXN0aW1hdGVkIHNhbXBsaW5nIGNvbXBsZXRpb247IGlmIGl0IGRpZCwgdGhhdCB3b3VsZCBiZSBhIGJpZyBwcm9ibGVtIGFuZCBJIHdvdWxkIGhhdmUgYSBsb3Qgb2YgZXhwbGFpbmluZyB0byBkbyB0byBteSBjb21taXR0ZWUuDQoNCmBgYHtyIFNhbXBsaW5nIHN1ZmZpY2llbmN5LCBlY2hvPUZBTFNFfQ0KZ2dwbG90KFJpY2hJbnRzLCBhZXMoeD1zaXRlc2l6ZXMkUXVhZHNBcmVhLCB5PVBlcmNDb21wbGV0ZSwgY29sb3I9ImJsYWNrIikpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIGNvbG9yPSJibGFjayIpKw0KICBnZW9tX3RleHQobGFiZWw9UmljaEludHMkU2l0ZSwgY29sb3I9ImJsYWNrIiwgc2l6ZT0zKSsNCiAgeWxhYigiRXN0aW1hdGVkICUgU3BlY2llcyBTYW1wbGVkIikrDQogIHhsYWIoZXhwcmVzc2lvbihRdWFkcmF0c35TYW1wbGVkL1NpdGV+QXJlYX4obV4yKSkpKw0KICBnZ3RpdGxlKCJFc3RpbWF0ZWQgc2FtcGxpbmcgY29tcGxldGlvbiBkb2VzIG5vdCBpbmNyZWFzZSB3aXRoIHNhbXBsaW5nIGVmZm9ydCIpKw0KICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoMCwgMTAwKSkrDQogIHRoZW1lKGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTQpLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKQ0KYGBgDQoNClRoZXJlIGlzIG5vIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNhbXBsaW5nIGVmZm9ydCBhbmQgY29tcGxldGlvbiBwZXJjZW50YWdlIChwPWByIGFSaWNoUXVhZFsxLDVdYCkuIEhvd2V2ZXIsIG5vdGUgdGhhdCBTaXRlcyAxMCBhbmQgMjYgd2VyZSBmbGFnZ2VkIGFzIG91dGxpZXJzIGJ5IHRoZSBhdXRvcGxvdCBmdW5jdGlvbi4gVGhpcyBpbmFkZXF1YXRlIHNhbXBsaW5nIGlzIGxpa2VseSB0aGUgcmVzdWx0IG9mIHRvbyBmZXcgcXVhZHJhdHMgc2FtcGxlZCBhdCB0aGUgd2V0bGFuZCBlZGdlIHJlbGF0aXZlIHRvIHRoZSBzaXplIG9mIHRoZSB3ZXRsYW5kLiANCg0KYGBge3IgR0xNIFByZXAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIGNoYW5nZSBuYS4gYWN0aW9uDQpvcHRpb25zKG5hLmFjdGlvbiA9ICJuYS5mYWlsIikNCg0KUmljaFNpdGVzPC1jYmluZChzaXRlc2l6ZXMsIFJpY2hJbnRzKQ0KUmljaFNpdGVzLnQgPC0gUmljaFNpdGVzWyAtYygxKSBdDQoNCm1vZGVsMTwtZ2xtKFJpY2huZXNzT2JzfkVuZERlcHRoK1N0YXJ0RGVwdGgrRGVwdGhDaGFuZ2UrTGF0aXR1ZGUrUGVybWFuZW5jZStBcmVhLCBkYXRhPSBSaWNoU2l0ZXMudCkNCg0KcmVzdWx0c21vZGVsPC1kcmVkZ2UobW9kZWwxKQ0KaW1wb3J0YW5jZShyZXN1bHRzbW9kZWwpDQpgYGANCg0KRGVwdGggY2hhbmdlIGJldHdlZW4gc3ByaW5nIGFuZCBmYWxsIHNhbXBsaW5nIGFwcGVhcnMgdG8gYmUgdGhlIG1vc3QgaW1wb3J0YW50IGZhY3RvciBkZXRlcm1pbmluZyBvYnNlcnZlZCBzaXRlLWxldmVsIHJpY2huZXNzLiANCg0KYGBge3J9DQoNCiMgY2hhbmdlIG5hLiBhY3Rpb24NCiMgb3B0aW9ucyhuYS5hY3Rpb24gPSAibmEuZmFpbCIpDQojIA0KIyBnbWUxPC0gZ2xtKFN1bX5EZXB0aCtDYW5vcHkrRGVwdGgqQ2Fub3B5K1NpdGU6SUQsIGRhdGE9IHF1YWR2YXJzc3VtcykNCg0KDQpgYGANCg0KDQojIyBFdmVubmVzcyBhbmQgRG9taW5hbmNlDQoNCjxmaWd1cmU+DQo8aW1nIHNyYz0iSW1hZ2VzL0dvb3NlY3JvcHBlZC5qcGciPjwvZmlndXJlPjxicj4NCg0KDQoNCmBgYHtyIFNpdGUgc2l6ZSBhbmQgcmljaG5lc3MgcGxvdCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChSaWNoSW50cywgYWVzKHg9c2l0ZXNpemVzJEFyZWEsIHk9UmljaEludHMkUmljaG5lc3NPYnMpKSArDQogIGdlb21fcG9pbnQoc2l6ZT0yKSsNCiAgeWxhYigiU2l0ZSByaWNobmVzcyIpKw0KICB4bGFiKGV4cHJlc3Npb24oU2l0ZX5hcmVhfihtXjIpKSkrDQogIGdndGl0bGUoIlNpdGUgYXJlYSBkb2VzIG5vdCBoYXZlIGEgcG9zaXRpdmUgYWZmZWN0IG9uIHNpdGUgcmljaG5lc3MiKSsNCiAgdGhlbWUoYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNCksIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpDQpgYGANCg0KVGhlcmUgYXBwZWFycyB0byBiZSBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNpdGUgcmljaG5lc3MgYW5kIHNpdGUgYXJlYSwgYnV0IHVuZXhwZWN0ZWRseSB0aGlzIHJlbGF0aW9uc2hpcCBhcHBlYXJzIHRvIGJlIG5lZ2F0aXZlLiBCZWNhdXNlIHRoZSBkYXRhIGFyZSBsaWtlbHkgbm9uLWxpbmVhciwgYSBnZW5lcmFsaXplZCBsaW5lYXIgbW9kZWwgc2hvdWxkIGJlIHVzZWQgdG8gYXNzZXNzIHRoaXMgcmVsYXRpb25zaGlwLg0KDQpgYGB7cn0NCmdncGxvdChSaWNoSW50cywgYWVzKHg9RG9taW5hbmNlLCB5PVJpY2huZXNzT2JzKSkgKw0KICBnZW9tX3BvaW50KHNpemU9MikrDQogIHhsYWIoIlNwZWNpZXMgRG9taW5hbmNlIChEKSIpKw0KICB5bGFiKCJTcGVjaWVzIFJpY2huZXNzIikrDQogIGdndGl0bGUoIlJpY2ggc2l0ZXMgaGF2ZSBsb3cgZG9taW5hbmNlIikNCmBgYA0KDQoNCg0KIyMgQ29tbXVuaXRpZXMNCg0KDQoNCg0KYGBge3IgTk1EUywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNsdXN0ZXI8LWhjbHVzdChzb3JlbnNlbiwgbWV0aG9kPSJhdmVyYWdlIikNCmdycDwtY3V0cmVlKGNsdXN0ZXIsNikNCnBsb3Qoc29yZW5zZW4ubm1kczAxLCB0eXBlPSJ0ZXh0IikNCm9yZGljbHVzdGVyKHNvcmVuc2VuLm5tZHMwMSwgY2x1c3RlciwgcHJ1bmUgPSA3LCBkaXNwbGF5ID0gInNpdGVzIiwNCiAgICAgICAgIHcgPSB3ZWlnaHRzKHNvcmVuc2VuLm5tZHMwMSwgZGlzcGxheSkpDQojIG9yZGllbGxpcHNlKHNvcmVuc2VuLm5tZHMwMSwgZ3JvdXA9Z3JwLCBkaXNwbGF5PSJzaXRlcyIsIGtpbmQ9Yygic2QiKSwgZHJhdz0ibGluZXMiLCBjb25mPTAuOTUsIGx3ZD0yLjYsIGNvbD0iZ3JleTQ0IikNCmBgYA0KDQojIyMgV2hpY2ggc2l0ZXMgYXJlIHNpbWlsYXI/DQoNClRoZXJlIG1heSBiZSBhIGxvdCBvZiBvdmVybGFwIGluIGNsdXN0ZXJzIGR1ZSB0byB0aGUgbmVzdGVkbmVzcyBvZiBzb21lIGNvbW11bml0eSB0eXBlcy4gV2Ugc2hvdWxkIHJldmlzaXQgdGhpcyBsYXRlciB1c2luZyBxdWFkcmF0cyBhcyByZXBsaWNhdGVzLg0KDQojIyMgQXJlIHNpdGVzIHNpbWlsYXIgYmVjYXVzZSB0aGV5J3JlIGdlb2dyYXBoaWNhbGx5IGNsb3Nlcj8NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgaGVhdG1hcENvbG9yRGlzdGFuY2Uoc29yZW5zZW4ubS50LCBtYWluID0gTlVMTCwNCiMgICBjb2xvclJhbXBQYWxldHRlKGMoInJveWFsYmx1ZTQiLCAiZ2hvc3R3aGl0ZSIpKSgyOTkpLCBtYXJnaW5zID0gYyg1LCA1KSkNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ2dwbG90KGRpc3RhbmNlLmYsIGFlcyh4PWRpc3RhbmNlLmYkZ2VvZ3JhcGhpYywgeT1kaXN0YW5jZS5mJFNvcmVuc2VuKSkgKw0KICBnZW9tX3BvaW50KCkrDQogIHlsYWIoIlNvcmVuc2VuIGRpc3NpbWlsYXJpdHkgaW5kZXgiKSsNCiAgeGxhYigiR2VvZ3JhcGhpYyBkaXN0YW5jZSAobSkiKSsNCiAgZ2d0aXRsZSgiR2VvZ3JhcGhpYyBkaXN0YW5jZSBiZXR3ZWVuIHNpdGVzIGhhcyBubyBlZmZlY3Qgb24gc3BlY2llcyBzaW1pbGFyaXR5IikrDQogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLCAxKSkNCmBgYA0KDQoNCg0KYGBge3J9DQptYW50ZWwoc29yZW5zZW4ubS50LCBkaXN0YW5jZS5tKQ0KYGBgDQoNCmBgYHtyfQ0KYWRvbmlzKHN1bXN1bXNQZXJtWywxOjMxMl1+UGVybWFuZW5jZSwgZGF0YT1zdW1zdW1zUGVybSwgbWV0aG9kPSJicmF5IiwgYmluYXJ5PVRSVUUpDQpgYGANCg0KDQoNCg0KT3JkaW5hdGlvbnMNCg0KYGBge3J9DQojIGNsdXN0ZXI8LWhjbHVzdChzb3JlbnNlbjAyLCBtZXRob2Q9ImF2ZXJhZ2UiKQ0KIyBncnA8LWN1dHJlZShjbHVzdGVyLDIwKQ0KcGxvdChzb3JlbnNlbi5ubWRzMDIpDQpgYGANCg0KDQpgYGB7cn0NCnF1YWRyYXQucmRhPC1yZGEoQWxsUG9uZHNbLTFdKQ0KDQpiaXBsb3QocXVhZHJhdC5yZGEsDQogICAgICAgZGlzcGxheT1jKCJzaXRlcyIsICJzcGVjaWVzIiksDQogICAgICAgdHlwZT1jKCJ0ZXh0IiwgInBvaW50cyIpKQ0Kb3JkaWh1bGwocXVhZHJhdC5yZGEsIGdyb3VwPUFsbFBvbmRzJFNpdGUpDQpgYGANCg0KDQojIyBJbXBsaWNhdGlvbnMNCg0KUGxhbnQgY29tbXVuaXRpZXMgYXJlbid0IHJlYWwuIFdlIGNhbiBhbGwgZ28gaG9tZSBub3cuDQoNCg0KYGBge3J9DQpiZWVwKHNvdW5kID0gMywgZXhwciA9IE5VTEwpDQpgYGANCg0K